<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.open-xchange.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Choeger</id>
	<title>Open-Xchange - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.open-xchange.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Choeger"/>
	<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=Special:Contributions/Choeger"/>
	<updated>2026-06-30T19:11:53Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=SourceCodeAccess&amp;diff=28908</id>
		<title>SourceCodeAccess</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=SourceCodeAccess&amp;diff=28908"/>
		<updated>2025-03-27T10:09:49Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= How to download the Open-Xchange source code =&lt;br /&gt;
&lt;br /&gt;
Starting with 6.22 the source code of Open-Xchange server is available from Git repositories.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following repositories exist:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! Repository&lt;br /&gt;
! content&lt;br /&gt;
|- &lt;br /&gt;
| https://gitlab.open-xchange.com/oss/appsuite/core/middleware&lt;br /&gt;
| The main repository containing most of the parts of Open-Xchange server&lt;br /&gt;
|-&lt;br /&gt;
| https://gitlab.open-xchange.com/frontend/core&lt;br /&gt;
| The user interface of OX App Suite&lt;br /&gt;
|-&lt;br /&gt;
| https://gitlab.open-xchange.com/appsuite/guard&lt;br /&gt;
| The server-code and UI for OX Guard (PGP implementation)&lt;br /&gt;
|-&lt;br /&gt;
| https://code.open-xchange.com/git/frontend6&lt;br /&gt;
| The AJAX user interface (version 6)&lt;br /&gt;
|-&lt;br /&gt;
| documentconverter-api&lt;br /&gt;
| The API of the server-based part of the documentconverter needed for OX Text&lt;br /&gt;
|-&lt;br /&gt;
| office&lt;br /&gt;
| The server-code for OX Text and OX Spreadsheet&lt;br /&gt;
|-&lt;br /&gt;
| office-web&lt;br /&gt;
| The frontend-code for OX Text and OX Spreadsheet&lt;br /&gt;
|-&lt;br /&gt;
| mobile-api-facade&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Git operations to access the code ==&lt;br /&gt;
&lt;br /&gt;
To clone a repository in case of gitlab please follow the instructions shown there.&lt;br /&gt;
For cloning from code.open-xchange.com, run&lt;br /&gt;
&lt;br /&gt;
 $ git clone https://code.open-xchange.com/git/&amp;lt;repository&amp;gt;&lt;br /&gt;
 $ cd &amp;lt;repository&amp;gt;&lt;br /&gt;
 $ git checkout -t origin/&amp;lt;branch&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The currently used Git branches ==&lt;br /&gt;
&lt;br /&gt;
For a list of available branches, run&lt;br /&gt;
&lt;br /&gt;
 $ git branch -r&lt;br /&gt;
&lt;br /&gt;
The main development process uses the following branches:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! Git branch&lt;br /&gt;
! content&lt;br /&gt;
|- &lt;br /&gt;
| develop&lt;br /&gt;
| head development&lt;br /&gt;
|-&lt;br /&gt;
| release-&amp;lt;version&amp;gt;&lt;br /&gt;
| stabilizing for &amp;lt;version&amp;gt; release&lt;br /&gt;
|-&lt;br /&gt;
| master&lt;br /&gt;
| maintenance of current release&lt;br /&gt;
|-&lt;br /&gt;
| master-&amp;lt;version&amp;gt;&lt;br /&gt;
| maintenance of previous releases&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: OX6]]&lt;br /&gt;
[[Category: AppSuite]]&lt;br /&gt;
[[Category: Developer]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=28028</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=28028"/>
		<updated>2023-03-02T12:18:35Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Generating the SOAP client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
; about dialogue: com.openexchange.appsuite.servercontact, see below&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'My Example Org | &amp;lt;a href=\\&amp;quot;https://www.example.org\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;www.example.org&amp;lt;/a&amp;gt; | &amp;lt;a href=\\&amp;quot;https://example.org/help\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;Contact us&amp;lt;/a&amp;gt;',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.appsuite.servercontact'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
'''Note that the below instructions only work with Java version 8 and no later version'''&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// insert in your imports section:&lt;br /&gt;
// import javax.xml.ws.BindingProvider;&lt;br /&gt;
((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
    ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
        .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
        .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME    = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME   = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();&lt;br /&gt;
&lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final long unifiedQuotaMax = 1000l;&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
        auser.setMaxQuota(unifiedQuotaMax);&lt;br /&gt;
&lt;br /&gt;
        // enable unified quota (might be enabled globally, already, though)&lt;br /&gt;
        final Entry unifiedQuota = new Entry();&lt;br /&gt;
        unifiedQuota.setKey(&amp;quot;com.openexchange.unifiedquota.enabled&amp;quot;);&lt;br /&gt;
        unifiedQuota.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        final SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
        configEntries.getEntries().add(unifiedQuota);&lt;br /&gt;
&lt;br /&gt;
        final SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        final SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
        auser.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), unifiedQuotaMax, oxaasCtxCreds);&lt;br /&gt;
&lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if (oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds)) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=27995</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=27995"/>
		<updated>2023-02-07T13:54:45Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
; about dialogue: com.openexchange.appsuite.servercontact, see below&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'My Example Org | &amp;lt;a href=\\&amp;quot;https://www.example.org\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;www.example.org&amp;lt;/a&amp;gt; | &amp;lt;a href=\\&amp;quot;https://example.org/help\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;Contact us&amp;lt;/a&amp;gt;',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.appsuite.servercontact'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// insert in your imports section:&lt;br /&gt;
// import javax.xml.ws.BindingProvider;&lt;br /&gt;
((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
    ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
        .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
        .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME    = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME   = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();&lt;br /&gt;
&lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final long unifiedQuotaMax = 1000l;&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
        auser.setMaxQuota(unifiedQuotaMax);&lt;br /&gt;
&lt;br /&gt;
        // enable unified quota (might be enabled globally, already, though)&lt;br /&gt;
        final Entry unifiedQuota = new Entry();&lt;br /&gt;
        unifiedQuota.setKey(&amp;quot;com.openexchange.unifiedquota.enabled&amp;quot;);&lt;br /&gt;
        unifiedQuota.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        final SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
        configEntries.getEntries().add(unifiedQuota);&lt;br /&gt;
&lt;br /&gt;
        final SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        final SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
        auser.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), unifiedQuotaMax, oxaasCtxCreds);&lt;br /&gt;
&lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if (oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds)) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=27992</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=27992"/>
		<updated>2023-02-07T13:53:18Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
; about dialogue: com.openexchange.appsuite.servercontact, see below&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'My Example Org | &amp;lt;a href=\\&amp;quot;https://www.example.org\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;www.example.org&amp;lt;/a&amp;gt; | &amp;lt;a href=\\&amp;quot;https://example.org/help\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;Contact us&amp;lt;/a&amp;gt;',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.appsuite.servercontact'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// insert in your imports section:&lt;br /&gt;
// import javax.xml.ws.BindingProvider;&lt;br /&gt;
((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
    ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
        .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
        .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME    = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME   = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();&lt;br /&gt;
&lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final long unifiedQuotaMax = 1000l;&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
        auser.setMaxQuota(unifiedQuotaMax);&lt;br /&gt;
&lt;br /&gt;
        // enable unified quota (might be enabled globally, already, though)&lt;br /&gt;
        final Entry unifiedQuota = new Entry();&lt;br /&gt;
        unifiedQuota.setKey(&amp;quot;com.openexchange.unifiedquota.enabled&amp;quot;);&lt;br /&gt;
        unifiedQuota.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        final SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
        configEntries.getEntries().add(unifiedQuota);&lt;br /&gt;
&lt;br /&gt;
        final SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        final SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
        auser.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), unifiedQuotaMax, oxaasCtxCreds);&lt;br /&gt;
&lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if (oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds)) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=Login_variations&amp;diff=26951</id>
		<title>Login variations</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=Login_variations&amp;diff=26951"/>
		<updated>2022-06-02T13:43:43Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Token Login */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;title&amp;quot;&amp;gt;Login variations&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Introduction:''' This paper describes Open-Xchanges's authentication and session handling. It gives an overview of all available mechanisms and on how to safely pass on sessions from external applications to the Open-Xchange Server (Single Sign On, SSO).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Open-Xchange Server web front-end is implemented in AJAX (Asynchronous JavaScript and XML). Thus the complete user interface (GUI) is running in a browser. Opposed to standard web applications there are no HTML pages generated and delivered by the browser.&lt;br /&gt;
&lt;br /&gt;
The complete user front-end is rendered and displayed in the browser. Based on HTTP/S  the data are exchanged with the server via JavaScript Object Notation (JSON). That means it is not possible to simulate front-end actions  via HTTP/S request by simulating respectively formatted GET/POST calls. Instead, another abstraction is taking place that exclusively transfers data from GUI to server and vice versa.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange Server includes a session daemon (sessiond) that keeps the current data of a logged in user. If successfully authenticated the information kept in the session are sufficient for accessing the Open-Xchange Server.&lt;br /&gt;
&lt;br /&gt;
==Access to IMAP Back-End services==&lt;br /&gt;
To access external E-Mail systems (IMAP/SMTP) the Open-Xchange Server has to know the credentials of the current user for the system, i. e. the session object has to keep the respective password for the access in plain text. That means authenticating via SessionIDs alone is not sufficient. Authentication always has to take place by entering the username and password.&lt;br /&gt;
&lt;br /&gt;
(There are two exceptions: either if one master password is used for all IMAP accounts, or if a very special implementation of MAL is used, which does not need a password.)&lt;br /&gt;
&lt;br /&gt;
==Basic Implementation Rules==&lt;br /&gt;
* It must not be possible to get a valid session by e. g. guessing a SessionID. This is especially important when being passed on by an external system&lt;br /&gt;
* A session must not be verified by a single SessionID only, but has to compare at least two different data types, this is what the Session-Secret is for&lt;br /&gt;
* Both SessionID and Session-Secret must never be passed from the Open-Xchange server to the client in the same request. This ensures, that potential issues in the stack between the client and Open-Xchange (proxies, caches, loadbalancer, Apache, …) can not lead to wrong sessions &lt;br /&gt;
* To enhance security Session-Secret and SessionID are transferred as different data types. The Session-Secret will always be transferred as a cookie, the SessionID will be transferred as URL parameter if persistent auto-login is not activated for this session.&lt;br /&gt;
* It must never be possible to have conflicting session information per client (multiple cookies) within the same cookie store&lt;br /&gt;
* If any error in the session handling is detected, the relevant request is discarded and logged. It is not tried to fix the issue&lt;br /&gt;
* In memory data (SessionID) of the browser GUI must never be changed during a valid session&lt;br /&gt;
* All relevant information regarding session management must always be written to the relevant logfiles&lt;br /&gt;
* The whole mechanism is only secure when being used via encrypted connection&lt;br /&gt;
* ATTENTION: If persistent autologin is activated for the system and a user decided to use it, all information necessary to access the Open-Xchange server is stored within the browsers cookie store.  This means, that the security of the whole system depends on the level of security of the browsers cookie store&lt;br /&gt;
&lt;br /&gt;
== Authentication and Session Tokens ==&lt;br /&gt;
Following tokens are used for the session management:&lt;br /&gt;
&lt;br /&gt;
=== SessionID ===&lt;br /&gt;
The SessionID is used to identify every session. It is a UUID, generated by the backend via default Java UUID implementation. It is written into the OX logfiles for every log message. When no auto-login is used for the session, then the SessionID is transferred as an URL parameter. If auto-login is activated, then the SessionID is transferred as a cookie.&lt;br /&gt;
&lt;br /&gt;
=== Session-Secret ===&lt;br /&gt;
The Session-Secret is used to verify every session. It is a UUID, generated by the backend via default Java UUID implementation. Only accesses, where the Session-Secret matches with the one stored in SessionD for the given SessionID are valid. Mismatches lead to immediate session termination.&lt;br /&gt;
&lt;br /&gt;
=== Public Session ===&lt;br /&gt;
The public Session is used as a replacement for the SessionID. It is a UUID, generated by the backend via default Java UUID implementation. The Public Session is transferred as a cookie named &amp;lt;tt&amp;gt;open-xchange-public-session-uuid&amp;lt;/tt&amp;gt;. Using the Public Session is limited to some non critical requests. By using this cookie instead of a request parameter, the browser is able to cache the response of special requests (e.g. contact images).&lt;br /&gt;
&lt;br /&gt;
=== Random ===&lt;br /&gt;
The Random-Token is a one time token with a limited lifetime, which is used to initiate sessions through 3rd party applications or websites. It is a UUID, generated by the backend via default Java UUID implementation. This token is deprecated and subject to change.&lt;br /&gt;
&lt;br /&gt;
=== Cookie Handling ===&lt;br /&gt;
In several situations, cookies are used to store and transfer the session tokens. The following rules for cookie creation and storage apply.&lt;br /&gt;
&lt;br /&gt;
==== Only one cookie per client session type ====&lt;br /&gt;
It must never happen, that the same client has more than one session associated with an Open-Xchange server. Therefore the cookies need to have the same name. If a new cookie is set to the browser, the original one will be overwritten. With the next client access either the SessionID or the Session-Secret do not match anymore and the invalid session is terminated.&lt;br /&gt;
Multiple clients with same cookie store.&lt;br /&gt;
&lt;br /&gt;
On the other hand it may happen, that several clients use the same cookie store. E.g. a standard browser GUI session and a browser plugin session. Therefore the cookie name needs to contain informations about the client.&lt;br /&gt;
&lt;br /&gt;
==== Naming of cookies ====&lt;br /&gt;
The cookies are named following this schema:&lt;br /&gt;
&lt;br /&gt;
  open-xchange-session-&amp;lt;&amp;lt;name token&amp;gt;&amp;gt;=&amp;lt;&amp;lt;SessionID&amp;gt;&amp;gt;&lt;br /&gt;
  open-xchange-secret-&amp;lt;&amp;lt;name token&amp;gt;&amp;gt;=&amp;lt;&amp;lt;Session-Secret&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;&amp;lt;name token&amp;gt;&amp;gt; is generated from configurable data associated with the client. It is a md5-hash build from the client-id and the User-Agent is used to identify the client. Other parameters can be added through a configuration file. If a request is performed by a browser with an invalid hash the corresponding cookies and session are invalidated.&lt;br /&gt;
&lt;br /&gt;
====Lifetime of cookies====&lt;br /&gt;
Normally, cookies are session cookies, which get invalid/deleted when the browser is shut down. &lt;br /&gt;
Using the persistent auto-login, the cookies are persistent cookies, with a configurable default. The default lifetime is one week.&lt;br /&gt;
&lt;br /&gt;
====Security of a cookie====&lt;br /&gt;
Cookies can be configured in different ways to be secure. For further information visit [[OXSessionSecurityFeatures]] &lt;br /&gt;
&lt;br /&gt;
All cookies get deleted when a logout is performed.&lt;br /&gt;
&lt;br /&gt;
==IP Check==&lt;br /&gt;
Per default an IP check is activated to terminate every session immediately, if the IP address of the client changes during the session lifetime. This check is not processed, when a session is reactivated following the persistent auto-login process.&lt;br /&gt;
There are several configuration options to enable, disable the IP Check and to define IP Ranges to omit the check and/or accept recurring connections from within these ranges. For further information on the configuration see [https://oxpedia.org/wiki/index.php?title=AppSuite:Configuration_properties_7.8.2 configuration properties].&lt;br /&gt;
&lt;br /&gt;
==Access via web browser with user credentials==&lt;br /&gt;
When directly logging in to the system by entering the credentials, following steps will be done to authenticate the user or verify the validity of the session after the authentication:&lt;br /&gt;
&lt;br /&gt;
# The browser sends initial request to the Open-Xchange server. The client represented by the application:&lt;br /&gt;
## is not authenticated yet&lt;br /&gt;
## has no cookie&lt;br /&gt;
## has no session ID.&lt;br /&gt;
# Open-Xchange server sends an AJAX application to browser.  The application is loaded into the browser and no data is exchanged between server and application.&lt;br /&gt;
# The AJAX application then will try to do an auto-login. Because the application has no knowledge of the cookies that may already be stored in the browser it will try to login the client. For further information on auto-login see [[OXSessionAutologin]]. With the precondition form 1. the auto-login try will be denied.&lt;br /&gt;
# The user enters username and password in the front-end.&lt;br /&gt;
# The username and password are sent to the server via JSON (SSL). If the user activated persistent auto-login on the login screen, this information is passed with the same request.&lt;br /&gt;
# The server authenticates the client and sends following data back to the browser via JSON (the data are saved in the session object):&lt;br /&gt;
## Session ID via JSON object&lt;br /&gt;
## (Optional) Random token for initial login via JSON object. For the random token to be send the server needs to be configured(see login.properties – com.openexchange.axaj.login.randomToken). CAUTION! The random token is deprecated and should no longer be used!&lt;br /&gt;
## Cookie with JSESSIONID. The JSESSIONID is set for loadbalancing to the browser&lt;br /&gt;
## Cookie containing the session secret. If persistent auto-login is selected, the cookie is configured with the relevant type and validity.&lt;br /&gt;
## Cookie containing the public identifier.&lt;br /&gt;
# The AJAX front-end saves the session ID in its memory. (Optional)  Ignores the random token.&lt;br /&gt;
# If the persistent auto-login is enabled the AJAX front-end will send a store request. If no error occurs a configured cookie with the relevant type and validity containing the session ID is set to the browser. &lt;br /&gt;
# The AJAX front-end sends initial data request via JSON to the Open-Xchange server and provides the session ID as an URL parameter. The secret is send along as a cookie.&lt;br /&gt;
# The Open-Xchange server processes this data request and compares:&lt;br /&gt;
## Session ID for validity in sessiond&lt;br /&gt;
## Session-Secret from the cookie for validity with session&lt;br /&gt;
# The request is correctly authenticated and is answered by the server.&lt;br /&gt;
# (Optional) Random token is discarded after timeout from sessiond.&lt;br /&gt;
# Repeat 9. - 11. until end of session&lt;br /&gt;
&lt;br /&gt;
If the user does not use the persistent auto-login, the session is only valid as long as the browser is opened. It will be cleared either on logout, on  browser termination or with any occurring error.&lt;br /&gt;
&lt;br /&gt;
For any details on the requests and responses please visit the [https://documentation.open-xchange.com/latest/middleware/http-api-gen/#_login_resource Technical Documentation]&lt;br /&gt;
&lt;br /&gt;
==Access via web browser after authentication with external system==&lt;br /&gt;
The goal is to authenticate in the Open-Xchange system through an external system and to safely pass on the received session data to a browser. To do so the external system has to know the user data (username, password) in plain text. &lt;br /&gt;
&lt;br /&gt;
The process is based on the session initialization in the Open-Xchange Server via the JSON interface and on passing on the received data to a browser. The browser finally initializes the session with an additional random token that is only valid for one single access. &lt;br /&gt;
#	External tool sends initial JSON request directly to Open-Xchange Server&lt;br /&gt;
##	not authenticated yet&lt;br /&gt;
##	no cookie&lt;br /&gt;
##	no SessionID&lt;br /&gt;
#	The Open-Xchange Server authenticates and delivers back following data to external tool via JSON (all the data are stored in the session object in sessiond)&lt;br /&gt;
##	SessionID in JSON object&lt;br /&gt;
##	Random token for initial login via JSON object (required for SSO login)&lt;br /&gt;
##	Cookie with Session-Secret is not set&lt;br /&gt;
#	External tool starts browser with special URL, that contains at least following data:&lt;br /&gt;
##	Random token for initial login&lt;br /&gt;
#	Open-Xchange Server compares:&lt;br /&gt;
##	Random token for validity in sessiond&lt;br /&gt;
#	Open-Xchange Server sends to the browser:&lt;br /&gt;
##	SessionID in JSON object&lt;br /&gt;
##	Cookie with JSESSIONID for loadbalancing is set to the browser&lt;br /&gt;
#	The second part of the tokens is delivered in a separate request&lt;br /&gt;
##	Cookie with Session-Secret is set to the browser If persistent auto-login is selected, the cookie is configured with the relevant type and validity&lt;br /&gt;
#	Open-Xchange removes random token from sessiond.&lt;br /&gt;
&lt;br /&gt;
Then the process continues as described in the section above. The session is then verified with the SessionID and Session-Secret.&lt;br /&gt;
&lt;br /&gt;
==Token Login==&lt;br /&gt;
A dedicated login action (tokenLogin) is used to acquire a server token bound to a given client token. The combination of these tokens allows another client to gain a valid session. This Login is intended to replace the random token login. With this method there is no request or response containing all necessary information to create a valid session.&lt;br /&gt;
&lt;br /&gt;
An example how to use this method to implement an external interactive login page using XHR can be found [[Tokenlogin_form|here]]&lt;br /&gt;
&lt;br /&gt;
See also the [https://documentation.open-xchange.com/components/middleware/http/7.10.6/index.html#!Login/doTokenLogin corresponding documentation in the OX HTTP API.]&lt;br /&gt;
&lt;br /&gt;
==Form Login==&lt;br /&gt;
The Form Login provides a simple way of accessing the web frontend just by using standard HTML forms. The response contains a redirect link to the Web-UI. See [[OXSessionFormLogin]] for details.&lt;br /&gt;
&lt;br /&gt;
==Redeem Token Login==&lt;br /&gt;
With a valid session it is possible to acquire a secret. Using this secret another system is able to generate a valid session.&lt;br /&gt;
This session may also contain the users password (configurable). The system in question needs to be registered at the server and has to identify itself with a key configured at the open-xchange server. This is only for internal communication and by default no keys are available.&lt;br /&gt;
&lt;br /&gt;
== Authentication against other services ==&lt;br /&gt;
OX6 and AppSuite allow authentication using other services, too. This is not in the scope of this article. The Services team is available to build plugins for such services. Some standard ones are already implemented, see the following articles for that:&lt;br /&gt;
* [[Authentication IMAP Plugin description]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For further information on the session see [[OXSessionLifecycle]].&lt;br /&gt;
&lt;br /&gt;
For further information on HTTP API visit the [https://documentation.open-xchange.com/latest/middleware/http-api-gen/#_login_resource Technical Documentation]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:OX6]]&lt;br /&gt;
[[Category:AppSuite]]&lt;br /&gt;
[[Category:Auth]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:File_Storages_per_User&amp;diff=26885</id>
		<title>AppSuite:File Storages per User</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:File_Storages_per_User&amp;diff=26885"/>
		<updated>2022-04-14T11:26:34Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* When is a user filestore enabled or when did a user has a own filestore? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.8.0}}&lt;br /&gt;
&lt;br /&gt;
= File Storages per user =&lt;br /&gt;
&lt;br /&gt;
This document tries to outline and explain the new concept of having the possibility to specify file storages on a per user basis that is introduced with Open‐Xchange Server v7.8.0.&lt;br /&gt;
&lt;br /&gt;
== The previous situation ==&lt;br /&gt;
&lt;br /&gt;
Before the introduction of the file storages per user feature, it was only possible to specify the file storage association per context.&lt;br /&gt;
That file storage was used for all modules/functions that are supposed to store/retrieve files:&lt;br /&gt;
* Drive&lt;br /&gt;
* Thumbnails&lt;br /&gt;
* PIM attachments&lt;br /&gt;
* Signature attachments&lt;br /&gt;
&lt;br /&gt;
File storages are registered and maintained in file store table held in configDb database. File storage obtains a unique identifier, a base URI and a size limitation.&lt;br /&gt;
&lt;br /&gt;
For each context a file storage identifier is specified alongside with a context quota that defines how much space that context is allowed to occupy in assigned file storage. Thus the sum of all quotas from those contexts assigned to file storage must not exceed the file storage’s size.&lt;br /&gt;
&lt;br /&gt;
[[Image:file_storage_picture1.png|One file storage per context|650px]]&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The motivation is to differentiate between file storages for common context‐associated files and Drive file. Those Drive files may further reside in the common context‐associated storage, but it also possible to specify user‐associated file storages where Drive files are maintained. The association is determined based on a folder's creator/owner: The quota gets accounted to that user that created a folder (provided the user has a user‐associated file storage).&lt;br /&gt;
&lt;br /&gt;
[[Image:file_storage_picture2.png|Differentiate|650px]]&lt;br /&gt;
&lt;br /&gt;
That kind of separation allows different provisioning scenarios that an administrator possibly wants to achieve. With regard to Drive files it is now possible to define per context that:&lt;br /&gt;
&lt;br /&gt;
* All Drive files reside in the file storage associated with the context, which is either automatically determined or explicitly set (through -F,--destination-store-id option) when creating a context. All Drive files (from users of that context) and all other file resources (Snippets, PIM attachments, ...) share the same quota usage and limit settings. The file storage associated with the context is called '''context file storage'''.&lt;br /&gt;
* Certain users are supposed to store their Drive files in their own file storage with individual quota settings different from the context file storage. All files created in Drive folders owned by such a user are then accounted to that user-associated file storage having their own quota usage and limitation. The user-associated file storage may be set on user creation as it is for context creation. The file storage associated with a user is called '''user file storage'''. Introducing a user file storage is suitable when an administrator wants to have user-sensitive quota settings for Drive files and/or wants to assign a different type of storage for Drive files uploaded by users; e.g. let seldom used/accessed file resources reside in context file storage, but let frequently, highly accessed Drive files reside in a better storage sink&lt;br /&gt;
* A certain user has his own (bigger) file storage for Drive files and other users of that context are supposed to use that file storage to share the quota usage and limitation specified for that file storage. A file storage owned by a user that is also used by other users is called '''master file storage'''.&lt;br /&gt;
&lt;br /&gt;
Having that possibilities of separation for quota usage and limitation it is possible to apply a certain use case scenario to contexts; e.g.&lt;br /&gt;
&lt;br /&gt;
* Slow mass storage vs. fast Drive storage setup&lt;br /&gt;
* OX Drive Stand‐Alone setup&lt;br /&gt;
&lt;br /&gt;
When assigning dedicated file storage for Drive to a certain user, the user’s file occupation is no more accounted to the overall context in which that user resides, but gets accounted to a dedicated user quota. Such a user quota can be used for different sales strategies that include tracking the user’s file occupation.&lt;br /&gt;
&lt;br /&gt;
To achieve the file storage association on a per user basis, the existing user table has been enhanced by file storage and quota information as it is for the context table. Moreover the filestore_usage table has also been enhanced by the capability to account storage occupation to a certain user&lt;br /&gt;
&lt;br /&gt;
[[Image:file_storage_picture3.png|Enhancements|650px]]&lt;br /&gt;
&lt;br /&gt;
In addition the user table has also been extended by filestore_owner column. That column is used to let a user’s file storage be combined with another user’s storage. This serves the scenario in which a grouped OX Drive Stand‐Alone setup is operated. Multiple users’ file occupation gets accounted to a master user account.&lt;br /&gt;
&lt;br /&gt;
Furthermore Open‐Xchange allows changing the running setups at any time to adjust the file storage usages/associations according to possibly changing needs/requirements.&lt;br /&gt;
&lt;br /&gt;
=== Note ===&lt;br /&gt;
&lt;br /&gt;
Please note that with introducing the concept of having user-associated file storages, the output for &amp;quot;listfilestore&amp;quot; command-line tool changed. Since also a user can be accounted to a file storage's capacity, the output changed to be:&lt;br /&gt;
&lt;br /&gt;
 /opt/open-xchange/sbin/listfilestore -A oxadminmaster -P secret&lt;br /&gt;
  id path                      size reserved used max-entities cur-entities&lt;br /&gt;
   2 file:///var/opt/filestore 1000      300    0         5000            2&lt;br /&gt;
&lt;br /&gt;
Hence, &amp;quot;maxctx&amp;quot; is replaced with &amp;quot;max-entities&amp;quot; and &amp;quot;curctx&amp;quot; is replaced with &amp;quot;cur-entities&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Seamless integration and flexibility ==&lt;br /&gt;
The new more flexible approach fits seamlessly into existing context/file storage setups. Thus there is no need to change anything, unless demanded by administrator&lt;br /&gt;
&lt;br /&gt;
=== The fall‐back setup ===&lt;br /&gt;
&lt;br /&gt;
[[Image:file_storage_picture4.png|The fall-back setup|650px]]&lt;br /&gt;
&lt;br /&gt;
Everything stays as is. There is a storage‐per‐context association and every file is held in that storage. There are no user‐specific file storage attributes set in user table.&lt;br /&gt;
&lt;br /&gt;
=== Slow mass storage vs. fast file storage setup ===&lt;br /&gt;
&lt;br /&gt;
[[Image:file_storage_picture5.png|Slow mass storage|650px]]&lt;br /&gt;
&lt;br /&gt;
There are two storages available: a file‐based and an S3 storage (assuming that the S3 one would be faster). While the context has the file‐based storage set, users in that context do have individual name spaces in the S3 storage.&lt;br /&gt;
&lt;br /&gt;
That way common files (PIM/Signature attachments, thumbnails) are stored to context‐ associated file‐based storage while Drive documents are stored in the individual user name spaces in the S3 storage. Every user is allowed to occupy up to 10GB of space in the S3 storage (this can be varied as well).&lt;br /&gt;
&lt;br /&gt;
=== OX Drive Stand‐Alone – Single User ===&lt;br /&gt;
&lt;br /&gt;
[[Image:file_storage_picture6.png|OX Drive Stand-Alone - Single User|650px]]&lt;br /&gt;
&lt;br /&gt;
Again there two file storages. Again the file‐based one is assumed to serve the slow mass storage behavior while S3 is assumed to be the fast storage.&lt;br /&gt;
&lt;br /&gt;
Context designated to the Single User scenario for OX Drive Stand‐Alone operation, do hold only one user that has its individual name space associated in the S3 storage.&lt;br /&gt;
&lt;br /&gt;
Again common files (PIM/Signature attachments, thumbnails) are stored in the context‐ associated file‐based storage while Drive documents are stored in the individual user name spaces in the S3 storage of each context. Every Drive document accounts the user‐sensitive quota of the associated user.&lt;br /&gt;
&lt;br /&gt;
=== OX Drive Stand‐Alone – Business Account ===&lt;br /&gt;
&lt;br /&gt;
[[Image:file_storage_picture7.png|OX Drive Stand-Alone - Business Account|650px]]&lt;br /&gt;
&lt;br /&gt;
There two different file storages as in the previous setups. Again the file‐based one is assumed to serve the slow mass storage behavior while S3 is assumed to be the fast storage.&lt;br /&gt;
&lt;br /&gt;
For this setup users do not hold their own individual name space in the S3 storage, but all share the same name space of the master user in the S3 storage. Moreover there are no dedicated user quotas, but all Drive documents do account to the master user’s quota&lt;br /&gt;
&lt;br /&gt;
== Extensions to provisioning command‐line tools ==&lt;br /&gt;
&lt;br /&gt;
=== createuser ===&lt;br /&gt;
&lt;br /&gt;
The existing createuser CLI is enhanced by the following options&lt;br /&gt;
 ‐q/‐‐quota The file storage quota in MB for associated user&lt;br /&gt;
 ‐f/‐‐filestore The identifier for the file storage.&lt;br /&gt;
 ‐o/‐‐owner The owner for the file storage. If no owner is given and f/filestore option is set, the user itself is taken as owner&lt;br /&gt;
&lt;br /&gt;
=== changeuser ===&lt;br /&gt;
&lt;br /&gt;
The existing changeuser CLI is enhanced by the following option&lt;br /&gt;
 ‐q/‐‐quota The file storage quota in MB for associated user&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Option ALLOW_CHANGING_QUOTA_IF_NO_FILESTORE_SET in file 'AdminUser.properties' controls if a user file storage is automatically enabled if the ‐q/‐‐quota option is given on a 'changeuser' invocation as an alternative to 'movecontextfilestore2user'. For users without a user file storage the 'changeuser' CLT needs to be called with a quota value different to unlimited (-1) and unlimited quota will only be enabled in case the user already has a user file storage.&lt;br /&gt;
&lt;br /&gt;
=== movecontextfilestore2user ===&lt;br /&gt;
&lt;br /&gt;
Move a user’s files from a context to an individual storage name space. &amp;lt;br&amp;gt;&lt;br /&gt;
Usage: movecontextfilestore2user&lt;br /&gt;
&lt;br /&gt;
 ‐h,‐‐help	Prints a help text&lt;br /&gt;
 ‐‐environment	Show info about commandline environment&lt;br /&gt;
 ‐‐nonl	Remove all newlines (\n) from output&lt;br /&gt;
 ‐i,‐‐userid &amp;lt;userid&amp;gt;	| Id of the user&lt;br /&gt;
 ‐u,‐‐username &amp;lt;username&amp;gt;	| Username of the user&lt;br /&gt;
 ‐A,‐‐adminuser &amp;lt;adminuser&amp;gt;	? Admin username&lt;br /&gt;
 ‐P,‐‐adminpass &amp;lt;adminpass&amp;gt;	? Admin password&lt;br /&gt;
 ‐c,‐‐contextid &amp;lt;contextid&amp;gt;	| The id of the context&lt;br /&gt;
 ‐N,‐‐contextname &amp;lt;contextname&amp;gt;	| context name&lt;br /&gt;
 ‐f,‐‐filestore &amp;lt;filestore&amp;gt;	* The identifier for the file storage.&lt;br /&gt;
 ‐q,‐‐quota &amp;lt;quota&amp;gt;	* The file storage quota in MB for associated user.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Entries marked with an asterisk (*) are mandatory.&lt;br /&gt;
Entries marked with an question mark (?) are mandatory depending on your configuration.&lt;br /&gt;
Entries marked with a pipe (|) are mandatory for one another which means that at least one of them must be set.&lt;br /&gt;
&lt;br /&gt;
=== moveuserfilestore2context ===&lt;br /&gt;
&lt;br /&gt;
The counterpart for the previous CLI. Move a user's files from his individual storage name space to the context storage name space.&amp;lt;br&amp;gt;&lt;br /&gt;
Usage: moveuserfilestore2context&lt;br /&gt;
&lt;br /&gt;
 ‐h,‐‐help	Prints a help text&lt;br /&gt;
 ‐‐environment	Show info about commandline environment&lt;br /&gt;
 ‐‐nonl	Remove all newlines (\n) from output&lt;br /&gt;
 ‐i,‐‐userid &amp;lt;userid&amp;gt;	| Id of the user&lt;br /&gt;
 ‐u,‐‐username &amp;lt;username&amp;gt;	| Username of the user&lt;br /&gt;
 ‐A,‐‐adminuser &amp;lt;adminuser&amp;gt;	? Admin username&lt;br /&gt;
 ‐P,‐‐adminpass &amp;lt;adminpass&amp;gt;	? Admin password&lt;br /&gt;
 ‐c,‐‐contextid &amp;lt;contextid&amp;gt;	| The id of the context&lt;br /&gt;
 ‐N,‐‐contextname &amp;lt;contextname&amp;gt;	| context name&lt;br /&gt;
&lt;br /&gt;
Entries marked with an asterisk (*) are mandatory.&lt;br /&gt;
Entries marked with an question mark (?) are mandatory depending on your configuration.&lt;br /&gt;
Entries marked with a pipe (|) are mandatory for one another that means that at least one of them must be set.&lt;br /&gt;
&lt;br /&gt;
=== moveuserfilestore2master ===&lt;br /&gt;
Move a user's files from his individual storage name space to the storage name space of specified master.&amp;lt;br&amp;gt;&lt;br /&gt;
Usage: moveuserfilestore2master&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ‐h,‐‐help	Prints a help text&lt;br /&gt;
 ‐‐environment	Show info about commandline environment&lt;br /&gt;
 ‐‐nonl	Remove all newlines (\n) from output&lt;br /&gt;
 ‐i,‐‐userid &amp;lt;userid&amp;gt;	| Id of the user&lt;br /&gt;
 ‐u,‐‐username &amp;lt;username&amp;gt;	| Username of the user&lt;br /&gt;
 ‐A,‐‐adminuser &amp;lt;adminuser&amp;gt;	? Admin username&lt;br /&gt;
 ‐P,‐‐adminpass &amp;lt;adminpass&amp;gt;	? Admin password&lt;br /&gt;
 ‐c,‐‐contextid &amp;lt;contextid&amp;gt;	| The id of the context&lt;br /&gt;
 ‐N,‐‐contextname &amp;lt;contextname&amp;gt;	| context name&lt;br /&gt;
 ‐m,‐‐master &amp;lt;master&amp;gt;	Master user id. If not set, the context administrator is assumed to be the master user.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Entries marked with an asterisk (*) are mandatory.&lt;br /&gt;
Entries marked with an question mark (?) are mandatory depending on your configuration.&lt;br /&gt;
Entries marked with a pipe (|) are mandatory for one another, which means that at least one of them, must be set.&lt;br /&gt;
&lt;br /&gt;
=== movemasterfilestore2user ===&lt;br /&gt;
Move a user's files from a master account name space to an individual storage name space.&amp;lt;br&amp;gt;&lt;br /&gt;
Usage: movemasterfilestore2user&lt;br /&gt;
&lt;br /&gt;
 ‐h,‐‐help	Prints a help text&lt;br /&gt;
 ‐‐environment	Show info about commandline environment&lt;br /&gt;
 ‐‐nonl	Remove all newlines (\n) from output&lt;br /&gt;
 ‐i,‐‐userid &amp;lt;userid&amp;gt;	| Id of the user&lt;br /&gt;
 ‐u,‐‐username &amp;lt;username&amp;gt;	| Username of the user&lt;br /&gt;
 ‐A,‐‐adminuser &amp;lt;adminuser&amp;gt;	? Admin username&lt;br /&gt;
 ‐P,‐‐adminpass &amp;lt;adminpass&amp;gt;	? Admin password&lt;br /&gt;
 ‐c,‐‐contextid &amp;lt;contextid&amp;gt;	| The id of the context&lt;br /&gt;
 ‐N,‐‐contextname &amp;lt;contextname&amp;gt;	| context name&lt;br /&gt;
 ‐m,‐‐master &amp;lt;master&amp;gt;	Master user id. If not set, the context administrator is assumed to be the master user.&lt;br /&gt;
 ‐f,‐‐filestore &amp;lt;filestore&amp;gt;	* The identifier for the file storage.&lt;br /&gt;
 ‐q,‐‐quota &amp;lt;quota&amp;gt;	* The file storage quota in MB for associated user.&lt;br /&gt;
&lt;br /&gt;
Entries marked with an asterisk (*) are mandatory.&lt;br /&gt;
Entries marked with an question mark (?) are mandatory depending on your configuration.&lt;br /&gt;
Entries marked with a pipe (|) are mandatory for one another, which means that at least one of them, must be set.&lt;br /&gt;
&lt;br /&gt;
=== Creating a user file storage ===&lt;br /&gt;
&lt;br /&gt;
Having the extensions to command-line tools a user-associated file storage can be enabled:&lt;br /&gt;
&lt;br /&gt;
* After using 'movecontextfilestore2user' command-line tool&lt;br /&gt;
* Using 'changeuser' command-line tool with quota and filestore options or only quota options and &amp;quot;ALLOW_CHANGING_QUOTA_IF_NO_FILESTORE_SET&amp;quot; set to &amp;quot;true&amp;quot; in 'AdminUser.properties' file&lt;br /&gt;
* By provisioning via 'createuser' command-line tool with quota and filestore options&lt;br /&gt;
&lt;br /&gt;
== Useful command‐line tools ==&lt;br /&gt;
&lt;br /&gt;
The following command‐line tools might be useful to get an overview&lt;br /&gt;
&lt;br /&gt;
* 'listfilestore' to list available file storages that can be assigned to contexts/users&lt;br /&gt;
* 'listcontext' to get the quota limit specified per context or -1 if none&lt;br /&gt;
* 'listuser' to get the quota limit specified per user or -1 if none&lt;br /&gt;
* 'listuserfilestores' to get a listing of users that use their own user file storage&lt;br /&gt;
&lt;br /&gt;
== FAQs ==&lt;br /&gt;
&lt;br /&gt;
=== When is a user filestore enabled or when does a user have an own filestore? ===&lt;br /&gt;
&lt;br /&gt;
A user filestore has an own filestore if a filestore is assigned to this user. This can either be done via the create and update clt's or via the movecontextfilestore2user clt.&lt;br /&gt;
&lt;br /&gt;
=== When is which quota affected? ===&lt;br /&gt;
&lt;br /&gt;
In case the user has no own filestore the quota of the context filestore is affected. In case the user has an own filestore or in case the user is a slave user of another users filestore the quota of this user filestore is affected.&lt;br /&gt;
&lt;br /&gt;
=== How can a user check his quota usage? ===&lt;br /&gt;
&lt;br /&gt;
The 'Quota' portal widget shows quota and usage.&lt;br /&gt;
&lt;br /&gt;
=== How to change the filestore quota shown in the portal widget? ===&lt;br /&gt;
&lt;br /&gt;
To change the quota one just has to use the changeuser or changecontext CLT with the --quota (-q) argument. E.g.:&lt;br /&gt;
&lt;br /&gt;
changecontext -A adminmaster -P masterpassword -c -q 1024&lt;br /&gt;
&lt;br /&gt;
=== How does quota work for public files? ===&lt;br /&gt;
&lt;br /&gt;
The quota of the folder creator/owner is in charge for files other users put inside. This affects the quota for users having an own filestore&lt;br /&gt;
&lt;br /&gt;
=== What happens with ownership of public files and folders when the creator/owner gets deleted? ===&lt;br /&gt;
&lt;br /&gt;
This depends which argument is used during the delete operation. In the default case, the context admin is assigned as the owner. But it is also possible that the data is assigned to a different user or that the data is completed removed.&lt;br /&gt;
&lt;br /&gt;
=== What happens in over quota scenarios by deleting users? ===&lt;br /&gt;
&lt;br /&gt;
If the data is assigned to a different user the quota limit is ignored. But the user (inheriting deleted user's files) is supposed to clean existing files as any attempt to create a Drive file will fail due to over-quota&lt;br /&gt;
&lt;br /&gt;
=== How to deal with quota issues for the context admin caused by public files? ===&lt;br /&gt;
&lt;br /&gt;
If the quota is too limited for the context admin the data should be completely removed or assigned to a different user. E.g.:&lt;br /&gt;
 deleteuser -A ctxadmin -P password -c -i --no-reassign&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:CrossContextDatabase&amp;diff=26372</id>
		<title>AppSuite:CrossContextDatabase</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:CrossContextDatabase&amp;diff=26372"/>
		<updated>2021-11-05T07:54:05Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;title&amp;quot;&amp;gt;Cross-context database&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{VersionFrom|7.8.0}}&lt;br /&gt;
&lt;br /&gt;
This article is valid from 7.8.0 to 7.10.1 and is not updated for newer versions anymore. For 7.10.2 and onwards you can find the corresponding documentation at https://documentation.open-xchange.com (currently https://documentation.open-xchange.com/latest/middleware/administration/global_database.html)&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
For storing data across context boundaries, a so called &amp;quot;global&amp;quot; database is used by the server. For example, such shared data could be information about guest users or data for registered OAuth applications. This article gives an overview about the basic concepts and how to setup a global database.&lt;br /&gt;
&lt;br /&gt;
== Register databases ==&lt;br /&gt;
&lt;br /&gt;
As a prerequisite, a global database needs to be registered in the Open-Xchange server's configuration database. At the storage layer, global databases are handled just like the ordinary &amp;lt;tt&amp;gt;context&amp;lt;/tt&amp;gt; databases storing all the existing groupware data. Therefore, the same underlying technologies can be used for replication like master/slave- or Galera-based setups, as well as registering additional database pools for sharding in very large installations. &lt;br /&gt;
&lt;br /&gt;
So, much similar to the groupware databases that store context-internal data, a new global database can be registered using the &amp;lt;tt&amp;gt;registerdatabase&amp;lt;/tt&amp;gt; commandline tool. To prevent the registered database being picked up for groupware data, set the &amp;lt;tt&amp;gt;maxunit&amp;lt;/tt&amp;gt; argument to &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 $ /opt/open-xchange/sbin/registerdatabase -A oxadminmaster -P admin_master_password --name oxglobal --hostname localhost --dbuser openexchange --dbpasswd db_password --master true --maxunit 0&lt;br /&gt;
 database 8 registered&lt;br /&gt;
&lt;br /&gt;
Remember the returned database identifier, &amp;lt;tt&amp;gt;8&amp;lt;/tt&amp;gt; in the above example, we'll need it at a later stage.&lt;br /&gt;
&lt;br /&gt;
Optionally, in case a database slave should be added, you can register it afterwards by specifying the database identifier as &amp;lt;tt&amp;gt;masterid&amp;lt;/tt&amp;gt; like follows:&lt;br /&gt;
&lt;br /&gt;
 $ /opt/open-xchange/sbin/registerdatabase -A oxadminmaster -P admin_master_password --name oxglobal_slave --hostname slave_host --dbuser openexchange --dbpasswd db_password --master false --maxunit 0 --masterid=8&lt;br /&gt;
 database 9 registered&lt;br /&gt;
&lt;br /&gt;
For smaller or test environments, it's also possible to re-use a previously registered groupware database for cross-context data, i.e. any database marked as &amp;lt;tt&amp;gt;master&amp;lt;/tt&amp;gt; by the &amp;lt;tt&amp;gt;listdatabase&amp;lt;/tt&amp;gt; utility may be used. Please note that all cross-context data is not accounted when calculating the database weight during context creation.&lt;br /&gt;
&lt;br /&gt;
== Context Groups ==&lt;br /&gt;
&lt;br /&gt;
As already mentioned, data inside the global database is shared between and available to all contexts in the installation. For setups serving multiple different &amp;quot;brands&amp;quot; or &amp;quot;domains&amp;quot;, this may not be the desired behavior, so that an additional level of data separation is needed for cross-context data. Therefore, one or more contexts can be classified into a specific &amp;quot;group&amp;quot;. The association with the group is done by assigning the property &amp;lt;tt&amp;gt;com.openexchange.context.group&amp;lt;/tt&amp;gt; to a context via config cascade. A context may only be part of one group, contexts without group association automatically fall into the &amp;quot;default&amp;quot; group. &lt;br /&gt;
&lt;br /&gt;
Please note that context group names must not be longer than 32 characters!&lt;br /&gt;
&lt;br /&gt;
As an example, a hoster is selling his hosted e-mail services under two different brands, called &amp;quot;Clever Hosting&amp;quot; and &amp;quot;Smart Hosting&amp;quot;. Each customer that registered an account at &amp;quot;Clever Hosting&amp;quot; now is put into the context group &amp;quot;clever_hosting&amp;quot; by setting the property &amp;lt;tt&amp;gt;com.openexchange.context.group&amp;lt;/tt&amp;gt; at any level of the config cascade, e.g. during provisioning when creating the context like: &lt;br /&gt;
&lt;br /&gt;
 $ /opt/open-xchange/sbin/createcontext [...] --config/com.openexchange.context.group=clever_hosting&lt;br /&gt;
&lt;br /&gt;
Or, if you already tagged your contexts with different taxonomy types (like &amp;lt;tt&amp;gt;clever&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;smart&amp;lt;/tt&amp;gt; in our example), the assignment to a context group can also be achieved at &amp;quot;ContextSet&amp;quot; level inside an &amp;lt;tt&amp;gt;.yml&amp;lt;/tt&amp;gt;-file of your &amp;lt;tt&amp;gt;contextSets&amp;lt;/tt&amp;gt; definitions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clever_group:&lt;br /&gt;
    withTags: clever&lt;br /&gt;
    com.openexchange.context.group: clever_hosting&lt;br /&gt;
    ui/product/name: &amp;quot;Clever Hosting&amp;quot;&lt;br /&gt;
    [...]&lt;br /&gt;
 &lt;br /&gt;
smart_group:&lt;br /&gt;
    withTags: smart&lt;br /&gt;
    com.openexchange.context.group: smart_hosting&lt;br /&gt;
    ui/product/name: &amp;quot;Smart Hosting&amp;quot;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the global database, the context group identifier serves as differentiating key for various data. For example, data of a guest user that was invited to a share in one context of a group can be used throughout all other contexts of the same group. Or, there may be a different set of registered OAuth applications available for each context group. Having contexts separated into different groups also allows to use different global databases as defined in the additional sections of the configuration file &amp;lt;tt&amp;gt;globaldb.yml&amp;lt;/tt&amp;gt;. The next chapter describes the global database configuration file in more detail.&lt;br /&gt;
&lt;br /&gt;
== Configure databases ==&lt;br /&gt;
&lt;br /&gt;
Global databases are defined in the configuration file &amp;lt;tt&amp;gt;globaldb.yml&amp;lt;/tt&amp;gt;. It mainly serves the purpose to map registered global databases to context groups. In case no advanced context grouping is necessary, e.g. because there's only a single brand in the installation, it's sufficient to supply the identifier of the previously registered master database, see [[#Register databases|Register databases]] above, inside the &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; section of the configuration file. For example, if the identifier of the global database master is &amp;lt;tt&amp;gt;8&amp;lt;/tt&amp;gt;, the section would look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
default:&lt;br /&gt;
    groups: [default]&lt;br /&gt;
    id: 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would lead to all cross-context data being stored at this database, assigning distinguished context groups as described in [[#Context Groups|Context Groups]] is not required. &lt;br /&gt;
&lt;br /&gt;
If there are multiple context groups, those can be directed to a specific global database by adding their names to the &amp;lt;tt&amp;gt;groups&amp;lt;/tt&amp;gt; property of a configuration section. For example, if the groups &amp;lt;tt&amp;gt;smart_hosting&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;clever_hosting&amp;lt;/tt&amp;gt; should use database &amp;lt;tt&amp;gt;8&amp;lt;/tt&amp;gt;, too, one could define:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
default:&lt;br /&gt;
    groups: [default,smart_hosting,clever_hosting]&lt;br /&gt;
    id: 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Removing the default group name &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; from the groups list is not recommended, and should only be done if you can ensure that each context of the installation has it's group assignment defined correctly in the property &amp;lt;tt&amp;gt;com.openexchange.context.group&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Having contexts separated into different groups also allows to use different global databases as defined in the additional sections of the configuration file &amp;lt;tt&amp;gt;globaldb.yml&amp;lt;/tt&amp;gt;. Since context groups are bound to a configuration section by specifying the group name in the &amp;quot;groups&amp;quot; array, and each configuration section may target another global database, in theory there could be as much global databases as there are defined context groups. For example, to enforce data from the context groups &amp;lt;tt&amp;gt;smart_hosting&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;clever_hosting&amp;lt;/tt&amp;gt; being stored at separate databases, the following configuration sections would route them to the database identifiers &amp;lt;tt&amp;gt;8&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; respectively:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clever:&lt;br /&gt;
    groups: [clever_hosting]&lt;br /&gt;
    id: 8&lt;br /&gt;
&lt;br /&gt;
smart:&lt;br /&gt;
    groups: [smart_hosting]&lt;br /&gt;
    id: 14&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reload global db configuration ==&lt;br /&gt;
&lt;br /&gt;
After updating the globaldb.yml you have to reload the server configuration by using /opt/open-xchange/sbin/reloadconfiguration command line tool.&lt;br /&gt;
&lt;br /&gt;
[[Category: AppSuite]]&lt;br /&gt;
[[Category: Administrator]]&lt;br /&gt;
[[Category: Database]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=26056</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=26056"/>
		<updated>2021-06-15T12:39:37Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* User creation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [https://www.open-xchange.com/portfolio/ox-dovecot-pro/ OX Dovecot Pro] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
; about dialogue: com.openexchange.appsuite.servercontact, see below&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'My Example Org | &amp;lt;a href=\\&amp;quot;https://www.example.org\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;www.example.org&amp;lt;/a&amp;gt; | &amp;lt;a href=\\&amp;quot;https://example.org/help\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;Contact us&amp;lt;/a&amp;gt;',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.appsuite.servercontact'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// insert in your imports section:&lt;br /&gt;
// import javax.xml.ws.BindingProvider;&lt;br /&gt;
((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
    ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
        .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
        .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME    = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME   = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();&lt;br /&gt;
&lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final long unifiedQuotaMax = 1000l;&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
        auser.setMaxQuota(unifiedQuotaMax);&lt;br /&gt;
&lt;br /&gt;
        // enable unified quota (might be enabled globally, already, though)&lt;br /&gt;
        final Entry unifiedQuota = new Entry();&lt;br /&gt;
        unifiedQuota.setKey(&amp;quot;com.openexchange.unifiedquota.enabled&amp;quot;);&lt;br /&gt;
        unifiedQuota.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        final SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
        configEntries.getEntries().add(unifiedQuota);&lt;br /&gt;
&lt;br /&gt;
        final SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        final SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
        auser.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), unifiedQuotaMax, oxaasCtxCreds);&lt;br /&gt;
&lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if (oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds)) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=26053</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=26053"/>
		<updated>2021-06-15T09:16:07Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* User creation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [https://www.open-xchange.com/portfolio/ox-dovecot-pro/ OX Dovecot Pro] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
; about dialogue: com.openexchange.appsuite.servercontact, see below&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'My Example Org | &amp;lt;a href=\\&amp;quot;https://www.example.org\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;www.example.org&amp;lt;/a&amp;gt; | &amp;lt;a href=\\&amp;quot;https://example.org/help\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;Contact us&amp;lt;/a&amp;gt;',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.appsuite.servercontact'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// insert in your imports section:&lt;br /&gt;
// import javax.xml.ws.BindingProvider;&lt;br /&gt;
((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
    ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
        .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
        .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME    = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME   = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();&lt;br /&gt;
&lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final long unifiedQuotaMax = 1000l;&lt;br /&gt;
        &lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
        auser.setMaxQuota(unifiedQuotaMax);&lt;br /&gt;
&lt;br /&gt;
        // enable unified quota (might be enabled globally, already, though)&lt;br /&gt;
        final SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        final SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
        final Entry unifiedQuota = new Entry();&lt;br /&gt;
        unifiedQuota.setKey(&amp;quot;com.openexchange.unifiedquota.enabled&amp;quot;);&lt;br /&gt;
        unifiedQuota.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
        configEntries.getEntries().add(unifiedQuota);&lt;br /&gt;
        final SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
        auser.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), unifiedQuotaMax, oxaasCtxCreds);&lt;br /&gt;
&lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if (oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds)) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:GuardCluster&amp;diff=25984</id>
		<title>AppSuite:GuardCluster</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:GuardCluster&amp;diff=25984"/>
		<updated>2021-05-21T13:07:35Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= OX Guard Clustering =&lt;br /&gt;
&lt;br /&gt;
== IMPORTANT ==&lt;br /&gt;
&lt;br /&gt;
'''If nothing else, make sure the oxguardpass file is the same for all Guard servers.  This is the local password file that is used to encrypt some database items.  If this varies between machines, there will be failures with password recoveries and cached key creation'''&lt;br /&gt;
&lt;br /&gt;
== Pre-Installation ==&lt;br /&gt;
&lt;br /&gt;
* Please make sure that the database is accessible from all of the Guard servers (usernames allow for the Guard IPs)&lt;br /&gt;
* Set up a filestore that can be accessed from all Guard servers.  This may be a Networked File Store (NAS), or Amazon&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
&lt;br /&gt;
==== OX Backends ====&lt;br /&gt;
&lt;br /&gt;
On each OX backend, make sure the packages open-xchange-rest and open-xchange-guard-backend are installed.  Edit the /opt/open-xchange/etc/server.properties file to make sure the REST API username and password are configured.  Please see the setup instructions for details.  &lt;br /&gt;
&lt;br /&gt;
==== First machine ====&lt;br /&gt;
&lt;br /&gt;
First, setup the guard.properties file to the needed settings.&lt;br /&gt;
&lt;br /&gt;
* Make sure that the com.openexchange.guard.storage.file.uploadDirectory setting refers to the NAS&lt;br /&gt;
* Make sure the right username/password for the REST API are set&lt;br /&gt;
* Make sure all database settings are set for names that can be used from all guard servers (i.e. don't use localhost)&lt;br /&gt;
* If installing on the same server as an OX backend, it is possible to use localhost as the restAPIHostname, but if not, make sure goes through the same load balancer or routing as the users&lt;br /&gt;
** Guard uses JSESSIONID, like the user interface, for routing&lt;br /&gt;
** Guard uses the users cookie data to authorize against the backend to retrieve emails, etc.&lt;br /&gt;
** If routed to a different backend than the user, there will be excess sessions created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the &amp;lt;code&amp;gt;/opt/open-xchange/sbin/guard --init&amp;lt;/code&amp;gt; '''on the first machine only'''&lt;br /&gt;
&lt;br /&gt;
Once init is done, the oxguardpass file will be created.  This file will need to be copied to all other Guard machines.&lt;br /&gt;
&lt;br /&gt;
==== Other machines ====&lt;br /&gt;
&lt;br /&gt;
Copy the oxguardpass file from the first installation into /opt/open-xchange/guard&lt;br /&gt;
Make sure that the guard.properties file for that machine is configured with the same required settings as the first.  You may be able to just copy the guard.properties file from the first depending on your setup.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Startup ===&lt;br /&gt;
&lt;br /&gt;
Once above is done, guard can be started.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:GuardCluster&amp;diff=25981</id>
		<title>AppSuite:GuardCluster</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:GuardCluster&amp;diff=25981"/>
		<updated>2021-05-21T12:46:40Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= OX Guard Clustering =&lt;br /&gt;
&lt;br /&gt;
== IMPORTANT ==&lt;br /&gt;
&lt;br /&gt;
'''If nothing else, make sure the oxguardpass file is the same for all Guard servers.  This is the local password file that is used to encrypt some database items.  If this varies between machines, there will be failures with password recoveries and cached key creation'''&lt;br /&gt;
&lt;br /&gt;
== Pre-Installation ==&lt;br /&gt;
&lt;br /&gt;
* Please make sure that the database is accessible from all of the Guard servers (usernames allow for the Guard IPs)&lt;br /&gt;
* Set up a filestore that can be accessed from all Guard servers.  This may be a Networked File Store (NAS), or Amazon&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
&lt;br /&gt;
==== OX Backends ====&lt;br /&gt;
&lt;br /&gt;
On each OX backend, make sure the packages open-xchange-rest and open-xchange-guard-backend are installed.  Edit the /opt/open-xchange/etc/server.properties file to make sure the REST API username and password are configured.  Please see the setup instructions for details.  &lt;br /&gt;
&lt;br /&gt;
==== First machine ====&lt;br /&gt;
&lt;br /&gt;
First, setup the guard.properties file to the needed settings.&lt;br /&gt;
&lt;br /&gt;
* Make sure that the com.openexchange.guard.storage.file.uploadDirectory setting refers to the NAS&lt;br /&gt;
* Make sure the right username/password for the REST API are set&lt;br /&gt;
* Make sure all database settings are set for names that can be used from all guard servers (i.e. don't use localhost)&lt;br /&gt;
* If installing on the same server as an OX backend, it is possible to use localhost as the restAPIHostname, but if not, make sure goes through the same load balancer or routing as the users&lt;br /&gt;
** Guard uses JSESSIONID, like the user interface, for routing&lt;br /&gt;
** Guard uses the users cookie data to authorize against the backend to retrieve emails, etc.&lt;br /&gt;
** If routed to a different backend than the user, there will be excess sessions created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the ./guard init on THE FIRST MACHINE ONLY&lt;br /&gt;
&lt;br /&gt;
Once init is done, the oxguardpass file will be created.  This file will need to be copied to all other Guard machines.&lt;br /&gt;
&lt;br /&gt;
==== Other machines ====&lt;br /&gt;
&lt;br /&gt;
Copy the oxguardpass file from the first installation into /opt/open-xchange/guard&lt;br /&gt;
Make sure that the guard.properties file for that machine is configured with the same required settings as the first.  You may be able to just copy the guard.properties file from the first depending on your setup.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Startup ===&lt;br /&gt;
&lt;br /&gt;
Once above is done, guard can be started.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:OX_Guard&amp;diff=25319</id>
		<title>AppSuite:OX Guard</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:OX_Guard&amp;diff=25319"/>
		<updated>2020-05-07T08:28:24Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Debian GNU/Linux 9.0 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= OX Guard (Version 2.10) =&lt;br /&gt;
&lt;br /&gt;
For previous versions of OX Guard, please click here&lt;br /&gt;
* [[AppSuite:OX_Guard_2-0 | Installation and information of OX Guard 2.0 - 2.2]]&lt;br /&gt;
* [[Appsuite:OX_Guard_2_8 | Installation and information of OX Guard 2.4 - 2.8]]&lt;br /&gt;
&lt;br /&gt;
If upgrading from 2.6 or 2.8, please see&lt;br /&gt;
* [[Appsuite:OX_Guard_Upgrade_2_10|Upgrading to 2.10]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
OX Guard is a fully integrated security add-on to OX App Suite that provides end users with a flexible email and file encryption solution. OX Guard is a highly scalable, multi server, feature rich solution that is so simple-to-use that end users will actually use it. With a single click a user can take control of their security and send secure emails and share encrypted files. This can be done from any device to both OX App Suite and non-OX App Suite users.&lt;br /&gt;
&lt;br /&gt;
OX Guard uses standard PGP encryption for the encryption of email and files. PGP has been around for a long time, yet has not really caught on with the masses. This is generally blamed on the confusion and complications of managing the keys, understanding trust, PGP format types, and lack of trusted central key repositories. Guard simplifies all of this, making PGP encryption as easy as a one click process, with no keys to keep track of, yet the options of advanced PGP management for those that know how.&lt;br /&gt;
&lt;br /&gt;
This article will guide you through the installation of Guard and describes the basic configuration and software requirements. As it is intended as a quick walk-through it assumes an existing installation of the operating system including a single server App Suite setup as well as average system administration skills. This guide will also show you how to setup a basic installation with none of the typically used distributed environment settings. The objective of this guide is:&lt;br /&gt;
&lt;br /&gt;
* To setup a single server installation&lt;br /&gt;
* To setup a single Guard instance on an existing Open-Xchange installation, no cluster&lt;br /&gt;
* To use the database service on the existing Open-Xchange installation for Guard, no replication&lt;br /&gt;
* To provide a basic configuration setup, no mail server configuration&lt;br /&gt;
&lt;br /&gt;
=== Key Features ===&lt;br /&gt;
&lt;br /&gt;
* Simple security at the touch of a button&lt;br /&gt;
* Provides user based security - Separate from provider&lt;br /&gt;
* Supplementary security to Provider based security - Layered&lt;br /&gt;
* Powerful features yet simple to use and understand&lt;br /&gt;
* Security - Inside and outside of the OX environment&lt;br /&gt;
* Email and Drive integration&lt;br /&gt;
* Uses proven PGP security&lt;br /&gt;
&lt;br /&gt;
=== Availability ===&lt;br /&gt;
&lt;br /&gt;
If an OX App Suite customer would like to evaluate OX Guard integration, the first step is to contact OX Sales. OX Sales will then work on the request and send prices and license/API (for the hosted infrastructure) key details to the customer.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
&lt;br /&gt;
Please review [https://oxpedia.org/wiki/index.php?title=AppSuite:OX_System_Requirements#OX_Guard OX Guard Requirements] for a full list of requirements.&lt;br /&gt;
&lt;br /&gt;
Since OX Guard is a Microservice it can either be added to an existing Open-Xchange installation or it can be deployed on a dedicated environment. The version of Guard installed is dependent on the Appsuite version installed.  Please refer to the version matrix below.&lt;br /&gt;
&lt;br /&gt;
==== Prerequisites ====&lt;br /&gt;
&lt;br /&gt;
* Open-Xchange REST API&lt;br /&gt;
* Grizzly HTTP connector (open-xchange-grizzly)&lt;br /&gt;
* A supported Java Virtual Machine (Java 8)&lt;br /&gt;
* An Open-Xchange App Suite installation (see version Matrix)&lt;br /&gt;
* Please Note: To get access to the latest minor features and bug fixes, you need to have a valid license. The article [https://oxpedia.org/wiki/index.php?title=AppSuite:UpdatingOXPackages Updating OX-Packages] explains how that can be done.&lt;br /&gt;
&lt;br /&gt;
==== Version Matrix ====&lt;br /&gt;
{|&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Core Version&lt;br /&gt;
! Guard Version&lt;br /&gt;
|-&lt;br /&gt;
|7.8.1&lt;br /&gt;
|2.4.0 or 2.4.2&lt;br /&gt;
|-&lt;br /&gt;
|7.8.2&lt;br /&gt;
|2.4.2&lt;br /&gt;
|-&lt;br /&gt;
|7.8.3&lt;br /&gt;
|2.6.0&lt;br /&gt;
|-&lt;br /&gt;
|7.8.4&lt;br /&gt;
|2.8.0&lt;br /&gt;
|-&lt;br /&gt;
|7.10.0&lt;br /&gt;
|2.10.0&lt;br /&gt;
|-&lt;br /&gt;
|7.10.1&lt;br /&gt;
|2.10.1&lt;br /&gt;
|-&lt;br /&gt;
|7.10.2&lt;br /&gt;
|2.10.2&lt;br /&gt;
|-&lt;br /&gt;
|7.10.3&lt;br /&gt;
|2.10.3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Important Notes ===&lt;br /&gt;
&lt;br /&gt;
==== Customisation ====&lt;br /&gt;
&lt;br /&gt;
OX Guard version supports branding / theming using the configuration cascade, defining a templateID for a user or context. Check the [https://oxpedia.org/wiki/index.php?title=AppSuite:GuardCustomization OX Guard Customisation] article for more details.&lt;br /&gt;
&lt;br /&gt;
==== Mail Resolver ====&lt;br /&gt;
&lt;br /&gt;
READ THIS VERY CAREFULLY; BEFORE PROCEEDING WITH GUARD INSTALLATION!&lt;br /&gt;
&lt;br /&gt;
The Guard installation must be able to determine if an email recipient is a local OX user or if it should be a guest account. The default MailResolver uses the context domain name to do this. On many installations, domains may extend across multiple context and multiple database shards. In these cases, the default MailResolver won't work. In addition, if a custom authentication package is used, the Mail Resolver will likely not work.&lt;br /&gt;
&lt;br /&gt;
Once Guard is installed, please be sure to test the mail resolver using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;/opt/open-xchange/sbin/guard test email@domain&amp;lt;/source&amp;gt;&lt;br /&gt;
to see if the mail Resolver works.&lt;br /&gt;
&lt;br /&gt;
If the test does not work, you will likely need a custom Mail Resolver. Please see [https://oxpedia.org/wiki/index.php?title=AppSuite:GuardMailResolver Mail Resolver] page&lt;br /&gt;
&lt;br /&gt;
This resolver software ''depends heavily on your local deployment''.&lt;br /&gt;
&lt;br /&gt;
== Download and Installation ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
&lt;br /&gt;
The installation of the &amp;lt;code&amp;gt;open-xchange-guard-backend-plugin&amp;lt;/code&amp;gt; package which is required for Guard and the main &amp;lt;code&amp;gt;open-xchange-guard&amp;lt;/code&amp;gt; package in version 2.4.0 or higher will eventually execute database update tasks if installed and activated. Please take this into account.&lt;br /&gt;
&lt;br /&gt;
There are several components to the Guard service. They can be all installed on the same server as the OX middleware or on a separate server.&lt;br /&gt;
&lt;br /&gt;
The components required for the OX middleware are: &amp;lt;code&amp;gt;open-xchange-rest&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;open-xchange-guard-backend-plugin&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;open-xchange-guard-ui&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The components required for the OX frontend are: &amp;lt;code&amp;gt;open-xchange-guard-ui-static&amp;lt;/code&amp;gt; and optionally &amp;lt;code&amp;gt;open-xchange-guard-help-en-us&amp;lt;/code&amp;gt; (or preferred language for help files).&lt;br /&gt;
&lt;br /&gt;
The components required for the Guard server &amp;lt;code&amp;gt;open-xchange-guard&amp;lt;/code&amp;gt; and either &amp;lt;code&amp;gt;open-xchange-guard-file-storage&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;open-xchange-guard-s3-storage&amp;lt;/code&amp;gt; depending on what storage you want to use. The examples below make use of the &amp;lt;code&amp;gt;open-xchange-guard-file-storage&amp;lt;/code&amp;gt;. Adjust the commands accordingly to fit your needs. In addition &amp;lt;code&amp;gt;open-xchange&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;open-xchange-core&amp;lt;/code&amp;gt; are required to run OX Guard.&lt;br /&gt;
&lt;br /&gt;
=== Debian Linux 8.0 (Jessie) ===&lt;br /&gt;
&lt;br /&gt;
Support of Debian Jessie is deprecated. Read More: https://forum.open-xchange.com/showthread.php?11205&lt;br /&gt;
&lt;br /&gt;
=== Debian Linux 9.0 (Stretch) ===&lt;br /&gt;
&lt;br /&gt;
If not already done, add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 deb https://software.open-xchange.com/products/guard/stable/guard/DebianStretch /&lt;br /&gt;
 deb https://software.open-xchange.com/products/appsuite/stable/backend/DebianStretch /&lt;br /&gt;
&lt;br /&gt;
and then run for a single node installation:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-rest open-xchange-guard open-xchange-guard-file-storage open-xchange-guard-ui open-xchange-guard-ui-static open-xchange-guard-backend-plugin&lt;br /&gt;
&lt;br /&gt;
or the following for a distributed installation:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-guard open-xchange-guard-file-storage&lt;br /&gt;
The packages &amp;lt;code&amp;gt;open-xchange-guard-ui&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;open-xchange-rest&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;open-xchange-guard-backend-plugin&amp;lt;/code&amp;gt; missing in the distributed installation have to be installed on the node running the middleware.  The package &amp;lt;code&amp;gt;open-xchange-guard-ui-static&amp;lt;/code&amp;gt; must be installed in the frontend (apache node).&lt;br /&gt;
&lt;br /&gt;
=== Debian Linux 10.0 (Buster) *Version 2.10.3+ only* ===&lt;br /&gt;
&lt;br /&gt;
If not already done, add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 deb https://software.open-xchange.com/products/guard/stable/guard/DebianBuster /&lt;br /&gt;
 deb https://software.open-xchange.com/products/appsuite/stable/backend/DebianBuster /&lt;br /&gt;
&lt;br /&gt;
and then run for a single node installation:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-rest open-xchange-guard open-xchange-guard-file-storage open-xchange-guard-ui open-xchange-guard-ui-static open-xchange-guard-backend-plugin&lt;br /&gt;
&lt;br /&gt;
or the following for a distributed installation:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-guard open-xchange-guard-file-storage&lt;br /&gt;
The packages &amp;lt;code&amp;gt;open-xchange-guard-ui&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;open-xchange-rest&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;open-xchange-guard-backend-plugin&amp;lt;/code&amp;gt; missing in the distributed installation have to be installed on the node running the middleware.  The package &amp;lt;code&amp;gt;open-xchange-guard-ui-static&amp;lt;/code&amp;gt; must be installed in the frontend (apache node).&lt;br /&gt;
&lt;br /&gt;
=== RedHat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
If not already done, add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 [open-xchange-guard-stable-guard]&lt;br /&gt;
 name=Open-Xchange-guard-stable-guard&lt;br /&gt;
 baseurl=https://software.open-xchange.com/products/guard/stable/guard/RHEL6/&lt;br /&gt;
 gpgkey=https://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
 [ox-backend]&lt;br /&gt;
 name=Open-Xchange-backend&lt;br /&gt;
 baseurl=https://software.open-xchange.com/products/appsuite/stable/backend/RHEL6/&lt;br /&gt;
 gpgkey=https://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and then run for a single node installation:&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
 $ yum install open-xchange-rest open-xchange-guard open-xchange-guard-file-storage open-xchange-guard-ui open-xchange-guard-ui-static open-xchange-guard-backend-plugin&lt;br /&gt;
or the following for a distributed installation:&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
 $ yum install open-xchange-guard open-xchange-guard-file-storage&lt;br /&gt;
The packages &amp;lt;code&amp;gt;open-xchange-guard-ui&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;open-xchange-rest&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;open-xchange-guard-backend-plugin&amp;lt;/code&amp;gt; missing in the distributed installation have to be installed on the node running the middleware.  The package &amp;lt;code&amp;gt;open-xchange-guard-ui-static&amp;lt;/code&amp;gt; must be installed in the frontend (apache node).&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
If not already done, add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 [open-xchange-guard-stable-guard]&lt;br /&gt;
 name=Open-Xchange-guard-stable-guard&lt;br /&gt;
 baseurl=https://software.open-xchange.com/products/guard/stable/guard/RHEL7/&lt;br /&gt;
 gpgkey=https://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
 [ox-backend]&lt;br /&gt;
 name=Open-Xchange-backend&lt;br /&gt;
 baseurl=https://software.open-xchange.com/products/appsuite/stable/backend/RHEL7/&lt;br /&gt;
 gpgkey=https://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and then run for a single node installation:&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
 $ yum install open-xchange-rest open-xchange-guard open-xchange-guard-file-storage open-xchange-guard-ui open-xchange-guard-ui-static open-xchange-guard-backend-plugin&lt;br /&gt;
or the following for a distributed installation:&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
 $ yum install open-xchange-guard open-xchange-guard-file-storage&lt;br /&gt;
&lt;br /&gt;
The packages &amp;lt;code&amp;gt;open-xchange-guard-ui&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;open-xchange-rest&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;open-xchange-guard-backend-plugin&amp;lt;/code&amp;gt; missing in the distributed installation have to be installed on the node running the middleware.  The package &amp;lt;code&amp;gt;open-xchange-guard-ui-static&amp;lt;/code&amp;gt; must be installed in the frontend (apache node).&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 ===&lt;br /&gt;
&lt;br /&gt;
Add the package repository using zypper if not already present:&lt;br /&gt;
&lt;br /&gt;
 $ zypper ar https://software.open-xchange.com/products/guard/stable/guard/SLE_12 guard-stable-guard&lt;br /&gt;
 $ zypper ar https://software.open-xchange.com/products/appsuite/stable/backend/SLE_12 ox-backend&lt;br /&gt;
&lt;br /&gt;
and then run for a single node installation:&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper in open-xchange-rest open-xchange-guard open-xchange-guard-file-storage open-xchange-guard-ui open-xchange-guard-ui-static&lt;br /&gt;
&lt;br /&gt;
or the following for a distributed installation:&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper in open-xchange-guard open-xchange-guard-file-storage&lt;br /&gt;
&lt;br /&gt;
The packages &amp;lt;code&amp;gt;open-xchange-guard-ui&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;open-xchange-rest&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;open-xchange-guard-backend-plugin&amp;lt;/code&amp;gt; missing in the distributed installation have to be installed on the node running the middleware.  The package &amp;lt;code&amp;gt;open-xchange-guard-ui-static&amp;lt;/code&amp;gt; must be installed in the frontend (apache node).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Univention Corporate Server ===&lt;br /&gt;
&lt;br /&gt;
If you have purchased the OX App Suite for UCS, the OX Guard is part of the offering. OX Guard is available in the Univention App Center. Please check the UMC module App Center for the installation of the OX Guard at your already available environment.&lt;br /&gt;
&lt;br /&gt;
Please note: By default, OX Guard generates the link to the secure content for external recipients on the basis of the local fully qualified domain name (FQDN). If the local FQDN is not reachable from the Internet, it has to be specified manually. This can be done by setting a UCR variable, e.g. via the UMC module &amp;amp;quot;Univention Configuration Registry&amp;amp;quot;. The variable has to contain the external FQDN of the OX Guard system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;oxguard/cfg/guard.properties/com.openexchange.guard.externalEmailURL=HOSTNAME.DOMAINNAME&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Update OX Guard ==&lt;br /&gt;
&lt;br /&gt;
This section contains information about updating a 2.10.0 version (e.g. for patch fixes). Upgrading from prior versions is discussed in different articles.&lt;br /&gt;
&lt;br /&gt;
=== Debian Linux 8.0 (Jessie) ===&lt;br /&gt;
&lt;br /&gt;
Support of Debian Jessie is deprecated. Read More: https://forum.open-xchange.com/showthread.php?11205&lt;br /&gt;
&lt;br /&gt;
=== Debian Linux 9.0 (Stretch) ===&lt;br /&gt;
&lt;br /&gt;
If not already done, add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 deb &amp;lt;https://LDBUSER:LDBPASSWORD@software.open-xchange.com/products/guard/stable/guard/updates/DebianStretch /&amp;gt;&lt;br /&gt;
 deb &amp;lt;https://LDBUSER:LDBPASSWORD@software.open-xchange.com/products/appsuite/stable/backend/DebianStretch /&amp;lt;/source&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then run:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get dist-upgrade&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to see, what apt-get is going to do without actually doing it, you can run:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get dist-upgrade -s&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
If not already done, add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 [open-xchange-guard-stable-guard-updates]&lt;br /&gt;
 name=Open-Xchange-guard-stable-guard-updates&lt;br /&gt;
 baseurl=https://LDBUSER:LDBPASSWORD@software.open-xchange.com/products/guard/stable/guard/updates/RHEL6/&lt;br /&gt;
 gpgkey=https://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
 [ox-backend]&lt;br /&gt;
 name=Open-Xchange-backend&lt;br /&gt;
 baseurl=https://LDBUSER:LDBPASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/RHEL6/&lt;br /&gt;
 gpgkey=https://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then run:&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
 $ yum upgrade&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
If not already done, add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 [open-xchange-guard-stable-guard-updates]&lt;br /&gt;
 name=Open-Xchange-guard-stable-guard-updates&lt;br /&gt;
 baseurl=https://LDBUSER:LDBPASSWORD@software.open-xchange.com/products/guard/stable/guard/updates/RHEL7/&lt;br /&gt;
 gpgkey=https://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
 [ox-backend]&lt;br /&gt;
 name=Open-Xchange-backend&lt;br /&gt;
 baseurl=https://LDBUSER:LDBPASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/RHEL7/&lt;br /&gt;
 gpgkey=https://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then run:&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
 $ yum upgrade&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 ===&lt;br /&gt;
&lt;br /&gt;
Add the package repository using &amp;lt;code&amp;gt;zypper&amp;lt;/code&amp;gt; if not already present:&lt;br /&gt;
&lt;br /&gt;
 $ zypper ar https://LDBUSER:LDBPASSWORD@software.open-xchange.com/products/guard/stable/guard/updates/SLE_12 guard-stable-guard-updates&lt;br /&gt;
 $ zypper ar https://LDBUSER:LDBPASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/SLE_12 ox-backend&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then run:&lt;br /&gt;
&lt;br /&gt;
 $ zypper dup -r guard-stable-guard-backend-updates&lt;br /&gt;
 $ zypper dup -r guard-stable-guard-ui-updates&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You might need to run:&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to update the repository metadata before running &amp;lt;code&amp;gt;zypper&amp;lt;/code&amp;gt; up.&lt;br /&gt;
&lt;br /&gt;
=== Univention Corporate Server ===&lt;br /&gt;
&lt;br /&gt;
If you have purchased the OX App Suite for UCS, the OX Guard is part of the offering. OX Guard is available in the Univention App Center. Please check the UMC module App Center for the update of the OX Guard.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
The following gives an overview of the most important settings to enable Guard for users on the Open-Xchange installation. Some of those settings have to be modified in order to establish the database and REST API access from the Guard service. All settings relating to the Guard backend component are located in the configuration file &amp;lt;code&amp;gt;guard-core.properties&amp;lt;/code&amp;gt; located in &amp;lt;code&amp;gt;/opt/open-xchange/etc&amp;lt;/code&amp;gt;. The default configuration should be sufficient for a basic &amp;amp;quot;up-and-running&amp;amp;quot; setup (with the exception of defining the database username and password). Please refer to the inline documentation of the configuration file for more advanced options. Additional information can be found in the [https://oxpedia.org/wiki/index.php?title=AppSuite:OX_Guard_Configuration_2_10 Guard Configuration] article.&lt;br /&gt;
&lt;br /&gt;
=== Basic Configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ vim /opt/open-xchange/etc/guard-core.properties&amp;lt;/source&amp;gt;&lt;br /&gt;
Guard database for storing Guard user information, main lookup tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.oxguardDatabaseHostname=localhost&amp;lt;/source&amp;gt;&lt;br /&gt;
Guard database that stores keys for guest users. May be the same as above. New guest shards will be created on this database as needed. If not supplied, will use the &amp;lt;code&amp;gt;oxguardDatabaseHostname&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.oxguardShardDatabase=localhost&amp;lt;/source&amp;gt;&lt;br /&gt;
Username and Password for the databases above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.databaseUsername=openexchange&lt;br /&gt;
com.openexchange.guard.databasePassword=db_password&amp;lt;/source&amp;gt;&lt;br /&gt;
Open-Xchange REST API host:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.restApiHostname=localhost&amp;lt;/source&amp;gt;&lt;br /&gt;
Open-Xchange REST API username and password (need to be defined in the OX backend in the &amp;amp;quot;Configure services&amp;amp;quot; below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.restApiUsername=apiusername&lt;br /&gt;
com.openexchange.guard.restApiPassword=apipassword&amp;lt;/source&amp;gt;&lt;br /&gt;
External URL for this Open-Xchange installation. This setting will be used to generate the link to the secure content for external recipients:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.externalEmailURL=URL_TO_OX&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Middleware Configuration on OX Guard node ===&lt;br /&gt;
&lt;br /&gt;
If you are installing OX Guard on a node that until yet did not host an Open-Xchange middleware you have to additionally configure some parts of the following properties files:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;configdb.properties&amp;lt;/code&amp;gt;: information about the existing configuration database.&lt;br /&gt;
* &amp;lt;code&amp;gt;server.properties&amp;lt;/code&amp;gt;: information about the connections have to be set.&lt;br /&gt;
* &amp;lt;code&amp;gt;system.properties&amp;lt;/code&amp;gt;: at least &amp;lt;code&amp;gt;SERVER_NAME&amp;lt;/code&amp;gt; should be set.&lt;br /&gt;
&lt;br /&gt;
=== Sevices Configuration ===&lt;br /&gt;
&lt;br /&gt;
==== Apache ====&lt;br /&gt;
&lt;br /&gt;
Configure the &amp;lt;code&amp;gt;mod_proxy_http&amp;lt;/code&amp;gt; module by adding the Guard API.&lt;br /&gt;
&lt;br /&gt;
===== Redhat Enterprise Linux 6 or CentOS 6 =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ vim /etc/httpd/conf.d/proxy_http.conf&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Debian GNU/Linux 9.0 =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ vim /etc/apache2/conf-enabled/proxy_http.conf&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Proxy balancer://oxguard&amp;gt;&lt;br /&gt;
        Order deny,allow&lt;br /&gt;
        Allow from all&lt;br /&gt;
 &lt;br /&gt;
        BalancerMember http://localhost:8009/ timeout=1800 smax=0 ttl=60 retry=60 loadfactor=100 route=OX1&lt;br /&gt;
        ProxySet stickysession=JSESSIONID|jsessionid scolonpathdelim=ON&lt;br /&gt;
       SetEnv proxy-initial-not-pooled&lt;br /&gt;
        SetEnv proxy-sendchunked&lt;br /&gt;
 &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ProxyPass /appsuite/api/oxguard balancer://oxguard/oxguard&lt;br /&gt;
 ProxyPass /pks balancer://oxguard/pgp&lt;br /&gt;
 ProxyPass /.well-known/openpgpkey/hu balancer://oxguard/hu&lt;br /&gt;
&lt;br /&gt;
'''Please Note''': The Guard API settings must be inserted '''''before''''' the existing &amp;lt;code&amp;gt;ProxyPass /appsuite/api&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
'''Also Note''':  If you already have a Proxy balancer for the OX backend with the same URL (say http://localhost:8080) then you don't need the second BalancerMember entry, and you can just have the ProxyPass address that balancer instead.&lt;br /&gt;
&lt;br /&gt;
After the configuration is done, restart the Apache webserver&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ apachectl restart&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Open-Xchange Middleware Configuration ===&lt;br /&gt;
&lt;br /&gt;
Edit the &amp;lt;code&amp;gt;guard-api.properties&amp;lt;/code&amp;gt; configuration file for the OX backend where the guard-backend-plugin was installed. Please remove comments in front of the following settings to the configuration file &amp;lt;code&amp;gt;guard-api.properties&amp;lt;/code&amp;gt; on the Open-Xchange backend servers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ vim /opt/open-xchange/etc/guard-api.properties&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;# OX Guard general permission, required to activate Guard in the AppSuite UI.&lt;br /&gt;
com.openexchange.capability.guard=true&lt;br /&gt;
&lt;br /&gt;
# Default theme template id for all users that have no custom template id configured.&lt;br /&gt;
com.openexchange.guard.templateID=0&amp;lt;/source&amp;gt;&lt;br /&gt;
Configure the API username and password that you assigned to Guard in the &amp;lt;code&amp;gt;server.properties&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ vim /opt/open-xchange/etc/server.properties&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;# Specify the user name used for HTTP basic auth by internal REST servlet&lt;br /&gt;
com.openexchange.rest.services.basic-auth.login=apiusername&lt;br /&gt;
&lt;br /&gt;
# Specify the password used for HTTP basic auth by internal REST servlet&lt;br /&gt;
com.openexchange.rest.services.basic-auth.password=apipassword&amp;lt;/source&amp;gt;&lt;br /&gt;
Finally, the OX backend needs to know where the Guard server is located. This is used to notify the Guard server of changes in users, and to send emails marked for signature. The URL for the Guard server should include the URL suffix &amp;lt;code&amp;gt;/guardadmin&amp;lt;/code&amp;gt;. In the event of a cluster setup, any Guard server can be referenced here, as it is not session specific, though ideally would have a HTTP load balancer/failover URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ vim /opt/open-xchange/etc/guard-api.properties&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;# Specifies the URI to the OX Guard end-point; e.g. http://guard.host.invalid:8081/guardadmin&lt;br /&gt;
# Default is empty&lt;br /&gt;
com.openexchange.guard.endpoint=http://guardserver:8009/guardadmin&amp;lt;/source&amp;gt;&lt;br /&gt;
Restart the OX backend&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/source&amp;gt;&lt;br /&gt;
==== SELinux ====&lt;br /&gt;
&lt;br /&gt;
Running SELinux prohibits your local Open-Xchange backend service to connect to localhost:8009, which is where the Guard backend service listens to. In order to allow localhost connections to 8009 execute the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ setsebool -P httpd_can_network_connect 1&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Generating the &amp;lt;code&amp;gt;oxguardpass&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Once the Guard configuration (database and backend configuration) and the service configuration has been applied, the Guard administration script needs to be executed in order to create the master password file in &amp;lt;code&amp;gt;/opt/open-xchange/etc/oxguardpass&amp;lt;/code&amp;gt;. The initiation only needs to be done '''once''' for a multi server setup, for details please see the sections '''Optional''' and/or '''Clustering'''.&lt;br /&gt;
&lt;br /&gt;
'''Please Note''': If you run a cluster of OX / Guard nodes, only execute this command on '''ONE''' node. Not on all nodes! See [https://oxpedia.org/wiki/index.php?title=AppSuite:GuardCluster OX Guard Clustering] for details.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ /opt/open-xchange/sbin/guard --init&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Please Note''': It is important to understand that the master password file located at &amp;lt;code&amp;gt;/opt/open-xchange/etc/oxguardpass&amp;lt;/code&amp;gt; is required to reset user passwords; without them the administrator will not be able to reset user passwords anymore in the future. The file contains the passwords used to encrypt the master database key, as well as passwords used to encrypt protected data in the users table. It must be the same on all Guard servers.&lt;br /&gt;
&lt;br /&gt;
=== Test Setup ===&lt;br /&gt;
&lt;br /&gt;
Not required, but it is a good idea to test the Guard setup before enabling for any users. The test function will verify that Guard has a good connection to the OX backend, and that it can resolve email addresses to users.&lt;br /&gt;
&lt;br /&gt;
To test, use an email address that exists on the OX backend (john@example.com for this example)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;/opt/open-xchange/sbin/guard --test john@example.com&amp;lt;/source&amp;gt;&lt;br /&gt;
Guard should return information from the OX backend regarding the user associated with &amp;amp;quot;john@example.com&amp;amp;quot;. Problems resolving information for the user should be resolved before using Guard. Check Rest API passwords and settings if errors returned.&lt;br /&gt;
&lt;br /&gt;
=== Enabling Guard for Users ===&lt;br /&gt;
&lt;br /&gt;
Guard provides two capabilities for users in the environment as well as a basic &amp;amp;quot;core&amp;amp;quot; level:&lt;br /&gt;
&lt;br /&gt;
* Guard: &amp;lt;code&amp;gt;com.openexchange.capability.guard&amp;lt;/code&amp;gt;&lt;br /&gt;
* Guard Mail: &amp;lt;code&amp;gt;com.openexchange.capability.guard-mail&amp;lt;/code&amp;gt;&lt;br /&gt;
* Guard Drive: &amp;lt;code&amp;gt;com.openexchange.capability.guard-drive&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;amp;quot;core&amp;amp;quot; Guard enabled a basic read functionality for Guard encrypted emails. We recommend enabling this for all users, as this allows all recipients to read Guard emails sent to them. Great opportunity for upsell. Recipients with only Guard enabled can then do a secure reply to the sender, but they can't start a new email or add recipients.&lt;br /&gt;
&lt;br /&gt;
'''Guard Mail''' and '''Guard Drive''' are additional options for users. &amp;amp;quot;Guard Mail&amp;amp;quot; allows users the full functionality of Guard emails. &amp;amp;quot;Guard Drive&amp;amp;quot; allows for encryption and decryption of drive files.&lt;br /&gt;
&lt;br /&gt;
Each of those two Guard components is enabled for all users that have the according capability configured. Please note that users need to have the Drive permission set to use Guard Drive. So the users that have Guard Drive enabled must be a subset of those users with OX Drive permission. Since v7.6.0 we enforce this via the default configuration. Those capabilities can be activated for specific user by using the Open-Xchange provisioning scripts:&lt;br /&gt;
&lt;br /&gt;
==== Guard Mail: ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ /opt/open-xchange/sbin/changeuser -c 1 -A oxadmin -P admin_password -u testuser --config/com.openexchange.capability.guard-mail=true&amp;lt;/source&amp;gt;&lt;br /&gt;
==== Guard Drive: ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ /opt/open-xchange/sbin/changeuser -c 1 -A oxadmin -P admin_password -u testuser --config/com.openexchange.capability.guard-drive=true&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Please Note''': Guard Drive requires Guard Mail to be configured for the user as well. In addition, these capabilities may be configured globally by editing the &amp;lt;code&amp;gt;guard-api.properties&amp;lt;/code&amp;gt; file on the OX backend.&lt;br /&gt;
&lt;br /&gt;
=== External Guest recipients: ===&lt;br /&gt;
Starting in Guard 2.10.0, when an encrypted email is sent to a user that does not have Guard, a guest account is created for them in appsuite.  The recipient uses the Guest account to read the encrypted email.  These guest users MUST have guard capabilities.  To do this, guard capability must be added to guest accounts.&lt;br /&gt;
&amp;lt;code&amp;gt;/opt/open-xchange/etc/share.properties&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.share.guestCapabilityMode=static&lt;br /&gt;
com.openexchange.share.staticGuestCapabilities=guard&amp;lt;/source&amp;gt;&lt;br /&gt;
In a distributed system, the Guest accounts should not be considered transient.  Guard servers must be able to verify the guest account exists in the session storage services.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.share.transientSessions=false&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Guest Storage ===&lt;br /&gt;
When an encrypted email is sent to an external Guest, a copy of the fully encrypted email is stored on the server.  This is used to create an inbox of encrypted emails for the guest.  By entering in a password, the emails can be decrypted and displayed.&lt;br /&gt;
&lt;br /&gt;
How these files are stored depend on which package, open-xchange-guard-file-storage or open-xchange-guard-s3-storage, was installed.&lt;br /&gt;
&lt;br /&gt;
The file retention policy is configured in the guard-core.properties file.&lt;br /&gt;
&lt;br /&gt;
=== Recipient key detection ===&lt;br /&gt;
&lt;br /&gt;
==== Local ====&lt;br /&gt;
&lt;br /&gt;
Guard needs to determine if an email recipients email address is an internal or external (non-ox) user.&lt;br /&gt;
&lt;br /&gt;
To detect if the recipient is an account on the same OX Guard system there is a mechanism needed to map a recipient mail address to the correct local OX context. The default implementation delivered in the product achieves that by looking up the mail domain (@example.com) within the list of context mappings. That is at least not possible in case of ISPs where different users/contexts use the same mail domain. In case your OX system does not use mail domains in context mappings it is required to deploy an OX OSGi bundle implementing the &amp;lt;code&amp;gt;com.openexchange.mailmapping.MailResolver&amp;lt;/code&amp;gt; class or by interfacing Guard with your mail resolver system. Please see [https://oxpedia.org/wiki/index.php?title=AppSuite:GuardMailResolver OX Guard Mail Resolver] for details.&lt;br /&gt;
&lt;br /&gt;
==== External ====&lt;br /&gt;
&lt;br /&gt;
Starting with Guard 2.0, Guard will use public PGP Key servers if configured to find PGP Public keys. In addition, Guard will also look up SRV records for PGP Key servers for a recipients domain. This follows the standards [http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#page-9 OpenPGP Draft].&lt;br /&gt;
&lt;br /&gt;
External PGP servers to use can be configured in the guard.properties file on the Guard servers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.publicPGPDirectory = hkp://keys.gnupg.net:11371, hkp://pgp.mit.edu:11371&amp;lt;/source&amp;gt;&lt;br /&gt;
If you would like this Guard installation discoverable by other Guard servers, then create an SRV record for each domain (&amp;amp;quot;example.com&amp;amp;quot; in this illustration):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;_hkp._tcp.example.com. 28800 IN    SRV     10 1 80 appsuite.example.com.&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Please Note''' PGP Public key servers by default append use the URL server/pks when the record is obtained from an SRV record. The proxy above routes anything with the Apache domain/pks to the OX Guard PGP server.&lt;br /&gt;
&lt;br /&gt;
Guard keys are also discoverable using the webkey service as specified here: https://tools.ietf.org/html/draft-koch-openpgp-webkey-service-02&lt;br /&gt;
This is enabled if you include the &lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;ProxyPass /.well-known/openpgpkey/hu balancer://oxguard/hu&amp;lt;/source&amp;gt;&lt;br /&gt;
in the proxy_http.conf as above.&lt;br /&gt;
&lt;br /&gt;
=== Clustering ===&lt;br /&gt;
&lt;br /&gt;
You can run multiple OX Guard servers in your environment to ensure high availability or enhance scalability. OX Guard integrates seamlessly into the existing Open-Xchange infrastructure by using the existing interface standards and is therefor transparent to the environment. A couple of things have to be prepared in order to loosely couple OX Guard servers with Open-Xchange servers in a cluster.&lt;br /&gt;
&lt;br /&gt;
==== MySQL ====&lt;br /&gt;
&lt;br /&gt;
The MySQL servers need to be configured in order to allow access to the configdb of Open-Xchange. To do so you need to set the following configuration in the MySQL &amp;lt;code&amp;gt;my.cnf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;bind = 0.0.0.0&amp;lt;/source&amp;gt;&lt;br /&gt;
This allows the Guard backend to bind to the MySQL host which is configured in the &amp;lt;code&amp;gt;guard-core.properties&amp;lt;/code&amp;gt; file with &amp;lt;code&amp;gt;com.openexchange.guard.configdbHostname&amp;lt;/code&amp;gt;. After the bind for the MySQL instance is configured and the OX Guard backend would be able to connect to the configured host, you have to grant access for the OX Guard service on the MySQL instance to manage the databases. Do so by connecting to the MySQL server via the MySQL client. Authenticate if necessary and execute the following, please note that you have to modify the hostname / IP address of the client who should be able to connect to this database, it should include all possible OX Guard servers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;GRANT ALL PRIVILEGES ON *.* TO 'openexchange'@'oxguard.example.com' IDENTIFIED BY ‘secret’;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Apache ====&lt;br /&gt;
&lt;br /&gt;
OX Guard uses the Open-Xchange REST API to store and fetch data from the Open-Xchange databases. The REST API is a servlet running in the Grizzly container. By default it is not exposed as a servlet through Apache and is only accessibly via port 8009. In order to use Apache's load balancing via &amp;lt;code&amp;gt;mod_proxy&amp;lt;/code&amp;gt; we need to add a servlet called &amp;amp;quot;preliminary&amp;amp;quot; to &amp;lt;code&amp;gt;proxy_http.conf&amp;lt;/code&amp;gt;, example based on a clustered &amp;lt;code&amp;gt;mod_proxy&amp;lt;/code&amp;gt;configuration:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Location /preliminary&amp;gt;&lt;br /&gt;
      Order Deny,Allow&lt;br /&gt;
      Deny from all&lt;br /&gt;
      # Only allow access from Guard servers within the network. Do not expose this&lt;br /&gt;
      # location outside of your network. In case you use a load balancing service in front&lt;br /&gt;
      # of your Apache infrastructure you should make sure that access to /preliminary will&lt;br /&gt;
      # be blocked from the Internet / outside clients. Examples:&lt;br /&gt;
      # Allow from 192.168.0.1&lt;br /&gt;
      # Allow from 192.168.1.1 192.168.1.2&lt;br /&gt;
      # Allow from 192.168.0.&lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ProxyPass /preliminary balancer://oxcluster/preliminary&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Make sure that the balancer is properly configured in the &amp;lt;code&amp;gt;mod_proxy&amp;lt;/code&amp;gt; configuration. Examples on how to do so can be found in our clustering configuration for Open-Xchange AppSuite. Like explained in the example above, please make sure that this location is only available in your internal network, there is no need to expose &amp;lt;code&amp;gt;/preliminary&amp;lt;/code&amp;gt; to the public, it is only used by Guard servers to connect to the OX backend. If you have a load balancer in front of the Apache cluster you should consider blocking access to &amp;lt;code&amp;gt;/preliminary&amp;lt;/code&amp;gt; from WAN to restrict access to the servlet to internal network services only.&lt;br /&gt;
&lt;br /&gt;
Now add the OX Guard &amp;lt;code&amp;gt;BalancerMembers&amp;lt;/code&amp;gt; to the oxguard balancer configuration (also in &amp;lt;code&amp;gt;proxy_http.conf&amp;lt;/code&amp;gt;) to address all your OX Guard nodes in the cluster in this balancer configuration. The configuration has to be applied to all Apache nodes within the cluster.&lt;br /&gt;
&lt;br /&gt;
If the Apache server is a dedicated server &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; instance you also have to install the OX Guard UI-Static package on all Apache nodes in the cluster in order to provide static files like images or CSS to the OX Guard client. Example for Debian (the OX Guard repository has to be configured in the package management prior):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ apt-get install open-xchange-guard-ui-static&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Open-Xchange ====&lt;br /&gt;
&lt;br /&gt;
Disable the Open-Xchange IPCheck for session verification. This is required because OX Guard will use the users session cookie to connect to the Open-Xchange REST API, but as a different IP address than the OX Guard server has been used during authentication the request would fail if you don't disable the IPCheck:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ vim /opt/open-xchange/etc/server.properties&amp;lt;/source&amp;gt;&lt;br /&gt;
and set:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.IPCheck=false&amp;lt;/source&amp;gt;&lt;br /&gt;
The OX Guard UI package has to be installed on all Open-Xchange backend nodes as well, example for Debian (the OX Guard repository has to be configured in the package management prior):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;$ apt-get install open-xchange-guard-ui&amp;lt;/source&amp;gt;&lt;br /&gt;
Restart the Open-Xchange service afterwards.&lt;br /&gt;
&lt;br /&gt;
==== OX Guard ====&lt;br /&gt;
&lt;br /&gt;
For details in clustering Guard servers, please see [https://oxpedia.org/wiki/index.php?title=AppSuite:GuardCluster OX Guard Clustering]. It is '''critical''' that all Guard servers have the same &amp;lt;code&amp;gt;oxguardpass&amp;lt;/code&amp;gt; file. Please see the clustering link for details. Do not run &amp;lt;code&amp;gt;/opt/open-xchange/sbin/guard --init&amp;lt;/code&amp;gt; on more than one server.&lt;br /&gt;
&lt;br /&gt;
After all the services like MySQL, Apache and Open-Xchange have been configured you need to update the OX Guard backend configuration to point to the correct API endpoints. Set the REST API endpoint to an Apache server by setting the following value in &amp;lt;code&amp;gt;/opt/open-xchange/etc/guard-core.properties&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.restApiHostname=apache.example.com&amp;lt;/source&amp;gt;&lt;br /&gt;
Per default Guard will try to connect to port 8009 to this host, but as we configured the REST API to be proxies thorugh the servlet &amp;lt;code&amp;gt;/preliminary&amp;lt;/code&amp;gt; on every Apache we now also need to change the target port for the REST API. You can do so by adding the following line into &amp;lt;code&amp;gt;/opt/open-xchange/etc/guard-core.properties&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;com.openexchange.guard.oxBackendPort=80&amp;lt;/source&amp;gt;&lt;br /&gt;
Please also change all settings in regards to MySQL like &amp;lt;code&amp;gt;com.openexchange.guard.configdbHostname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;com.openexchange.guard.oxguardDatabaseHostname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;com.openexchange.guard.databaseUsername&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;om.openexchange.guard.databasePassword&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Afterwards restart the OX Guard service and check the log file if the OX Guard backend is able to connect to the configured REST API.&lt;br /&gt;
&lt;br /&gt;
=== Multi Node ===&lt;br /&gt;
&lt;br /&gt;
If you have multiple OX and Guard installations, please see the following documentation [https://oxpedia.org/wiki/index.php?title=AppSuite:OX_Guard_Modular OX Guard Modular Setup].&lt;br /&gt;
&lt;br /&gt;
== Support API ==&lt;br /&gt;
&lt;br /&gt;
The OX Guard Support API enables administrative access to various functions for maintaining OX Guard from a client in a role as a support employee. A client has to do a BASIC AUTH authentication in order to access the API. Username and password can be configured in the guard-core.properties file using the following settings:&lt;br /&gt;
&lt;br /&gt;
 # Specify the username and password for accessing the Support API of Guard&lt;br /&gt;
 com.openexchange.guard.supportApiUsername=&lt;br /&gt;
 com.openexchange.guard.supportApiPassword=&lt;br /&gt;
&lt;br /&gt;
In contrast to the rest of the OX Guard requests, the OX Guard support API requests are accessible using: /guardsupport. This distinction allows more flexible configuration since the support API should not always be accessible from everywhere. &lt;br /&gt;
&lt;br /&gt;
'''Warning''': Exposing the support API to the internet could be huge security risk. Only add to Apache if you know what you are doing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Reset password ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;POST /guardsupport/?action=reset_password&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Performs a password reset and sends a new random generated password to a specified email address by the user or a default address if the user did not specify an email address. (''Since Guard 2.0'')&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; – The email address of the user to reset the password for&lt;br /&gt;
* &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt; (optional) – The email address to send the new password to, if the user did not specify a secondary email address&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
PRIMARY if the reset was sent to the primary email address.  SECONDARY if the reset email was sent to the secondary email address that the user specified&lt;br /&gt;
&lt;br /&gt;
=== Expose key ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;POST /guardsupport/?action=expose_key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Marks a deleted user key temporary as “exposed” and creates a unique URL for downloading the exposed key. Automatic resetting of exposed keys to &amp;amp;quot;not exposed&amp;amp;quot; is scheduled once a day and resets all exposed keys which have been exposed before X hours, where X can be configured using com.openexchange.guard.exposedKeyDurationInHours in the guard.properties files. (''Since Guard 2.0'')&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; – The email address of the user to expose the deleted keys for&lt;br /&gt;
* &amp;lt;code&amp;gt;cid&amp;lt;/code&amp;gt; – The context id&lt;br /&gt;
&lt;br /&gt;
Response: A URL pointing to the downloadable exposed keys.&lt;br /&gt;
&lt;br /&gt;
=== Delete user ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;POST /guardsupport/?action=delete_user&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deletes all keys related to a certain user. The keys are backed up and can be exposed using the “expose_key” call. (''Since Guard 2.0'')&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt; – The user's id&lt;br /&gt;
* &amp;lt;code&amp;gt;cid&amp;lt;/code&amp;gt; - The context id&lt;br /&gt;
&lt;br /&gt;
=== Upgrade User (Release 2.10 and later) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;POST /guardsupport/?action=upgrade_guest&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upgrades a Guest account.  This action copies all of the keys from the Guest account to a full OX account, assuming that user has Guard capabilities.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; - The email address of the Guest user&lt;br /&gt;
* &amp;lt;code&amp;gt;user_id&amp;lt;/code&amp;gt; – The user's new id&lt;br /&gt;
* &amp;lt;code&amp;gt;cid&amp;lt;/code&amp;gt; - The user's new context id&lt;br /&gt;
&lt;br /&gt;
== Customisation ==&lt;br /&gt;
&lt;br /&gt;
Guard's templates are customisable at the user and context level. Please see [https://oxpedia.org/wiki/index.php?title=AppSuite:GuardCustomization Customisation] for details.&lt;br /&gt;
&lt;br /&gt;
== Entropy ==&lt;br /&gt;
&lt;br /&gt;
Guard requires entropy (randomness) to generate the private/public keys that are used. Depending on the server and it's environment, this may become a problem. Please see [https://oxpedia.org/wiki/index.php?title=AppSuite:GuardEntropy Entropy] for a possible solution.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=25312</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=25312"/>
		<updated>2020-04-21T11:07:12Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Create a context */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [https://www.open-xchange.com/portfolio/ox-dovecot-pro/ OX Dovecot Pro] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
; about dialogue: com.openexchange.appsuite.servercontact, see below&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'My Example Org | &amp;lt;a href=\\&amp;quot;https://www.example.org\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;www.example.org&amp;lt;/a&amp;gt; | &amp;lt;a href=\\&amp;quot;https://example.org/help\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;Contact us&amp;lt;/a&amp;gt;',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.appsuite.servercontact'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// insert in your imports section:&lt;br /&gt;
// import javax.xml.ws.BindingProvider;&lt;br /&gt;
((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
    ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
        .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
        .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=25311</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=25311"/>
		<updated>2020-04-21T10:56:58Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* userAttributes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [https://www.open-xchange.com/portfolio/ox-dovecot-pro/ OX Dovecot Pro] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'My Example Org | &amp;lt;a href=\\&amp;quot;https://www.example.org\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;www.example.org&amp;lt;/a&amp;gt; | &amp;lt;a href=\\&amp;quot;https://example.org/help\\&amp;quot; target=\\&amp;quot;_blank\\&amp;quot;&amp;gt;Contact us&amp;lt;/a&amp;gt;',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.appsuite.servercontact'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// insert in your imports section:&lt;br /&gt;
// import javax.xml.ws.BindingProvider;&lt;br /&gt;
((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
    ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
        .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
        .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Documents_Installation_Guide&amp;diff=25210</id>
		<title>AppSuite:Documents Installation Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Documents_Installation_Guide&amp;diff=25210"/>
		<updated>2020-01-21T07:58:39Z</updated>

		<summary type="html">&lt;p&gt;Choeger: either sudo or not sudo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.10.3}}&lt;br /&gt;
&lt;br /&gt;
For earlier versions see ''[[AppSuite:Documents_Installation_Guide_7.10.2_and_earlier|Guide for 7.10.2]]''&lt;br /&gt;
&lt;br /&gt;
= Download &amp;amp; Installation OX Documents =&lt;br /&gt;
&lt;br /&gt;
=== General Information ===&lt;br /&gt;
&lt;br /&gt;
OX Documents are browser based, cloud ready, text, spreadsheet and presentation products that can work with Microsoft Office and OpenOffice documents in a lossless way. And you can also collaborate with other people to edit shared documents on various devices.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
See the [[AppSuite:OX_System_Requirements|Open-Xchange software requirements page]] for details. Additionally the support of websockets proxy by the webserver or loadbalancer is required, this is e.g. available in Apache 2.4.10 and higher. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OX Documents needs to be installed in an OX App Suite configuration with a [[AppSuite:Grizzly|backend based on Grizzly]] (including hazelcast as installed and activated by default).&lt;br /&gt;
&lt;br /&gt;
For compatibility with the legacy MS binary format files (.DOC, .XLS, .PPT) and for printing functionality in OX Text the document converter components (incl. readerengine) are required. These are not available in the Community Version of OX AppSuite.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Mandatory Modules ==&lt;br /&gt;
&lt;br /&gt;
Additional functional modules need to be installed separately: &lt;br /&gt;
&lt;br /&gt;
* The Document Converter API: See [[AppSuite:DocumentConverterAPIInstall|Document converter API installation instructions]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
The OX Documents deployment consists of the packages &amp;lt;tt&amp;gt;open-xchange-documents-backend&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;open-xchange-documents-ui&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;open-xchange-documents-backend&amp;lt;/tt&amp;gt; package also requires and installs these packages:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-file-distribution&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-sessionstorage-hazelcast&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Packages are no longer needed since 7.10.3&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-realtime-core&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-realtime-json&amp;lt;/tt&amp;gt;&lt;br /&gt;
Furthermore all &amp;lt;tt&amp;gt;open-xchange-realtime-*&amp;lt;/tt&amp;gt; packages will be replaced with empty transitive packages to remove relicts of the realtime framework.&lt;br /&gt;
&lt;br /&gt;
The package &amp;lt;tt&amp;gt;open-xchange-documents-collaboration&amp;lt;/tt&amp;gt; has been introduced with 7.10.3. It provides the Documents Collaboration Service (see below).&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
 $ yum install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static documents-collaboration&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
The Apache version 2.2 provided with RHEL6 does not support websockets. &lt;br /&gt;
Please use Apache version 2.4.x available with RHSCL or any other capable loadbalancer.'''&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL7|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL7|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 9.0 (valid from v7.10) ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianStretch|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianStretch|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 10.0 (valid from v7.10.3) ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianBuster|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianBuster|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 === &lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Univention Corporate Server ===&lt;br /&gt;
&lt;br /&gt;
OX Text for OX App Suite for UCS is available in the Univention App Center. Please check the UMC module App Center for the installation of the OX Documents at your already available environment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Documents Collaboration Service ==&lt;br /&gt;
&lt;br /&gt;
Starting with release 7.10.3 the Documents Collaboration Service (DCS) has been introduced.&lt;br /&gt;
&lt;br /&gt;
The DCS needs to be installed, configured and run. It supports collaboration across Middleware nodes but is also mandatory for small (even single node) environments.&lt;br /&gt;
The server can be run as one additional service (JVM) or - for larger deployments - several instances can be clustered.&lt;br /&gt;
The implementation is based on Spring Boot and uses the Java-based messaging server Apache ActiveMQ.&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
For upgrades from earlier versions than 7.10.2 the hazelcast cluster requires a complete shutdown, since the internal OX Documents data has changed. A rolling upgrade is not possible.'''&lt;br /&gt;
&lt;br /&gt;
=== Documents Collaboration Service (DCS) ===&lt;br /&gt;
&lt;br /&gt;
Prepare documents-collaboration repository as described above.&lt;br /&gt;
&lt;br /&gt;
The DCS will be installed via the package:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
open-xchange-documents-collaboration&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The target directory is &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DCS configuration file is located at &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt;. All available configuration items are described on this [https://documentation.open-xchange.com/components/documents/documents-collaboration/config/7.10.3/#mode=features&amp;amp;feature=DocumentsCollaboration%20Server page]&lt;br /&gt;
&lt;br /&gt;
The following entries need to be reviewed and values need to be adjusted during the setup.&amp;lt;br&amp;gt;&lt;br /&gt;
Configure bind host IP and JMS Port to listen to&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dcs.host = 192.168.10.25       # Interface of the DCS node&lt;br /&gt;
dcs.port = 61616&lt;br /&gt;
&amp;lt;/pre&amp;gt;           &lt;br /&gt;
&lt;br /&gt;
A DCS writes its own connection data, retrieved from its configuration file during startup of the service, to a database to be discovered by Middleware nodes. &lt;br /&gt;
&lt;br /&gt;
'''Caveat:&amp;lt;/br&amp;gt;&lt;br /&gt;
In a distributed setup DCSs may be installed on separate nodes. If such a DCS node has different internal and external IP addresses one needs to make sure that a middleware node has the correct DCS address to connect to.&lt;br /&gt;
The config item &amp;lt;tt&amp;gt;advertiseURL&amp;lt;/tt&amp;gt; can be set to the name of the DCS node.&lt;br /&gt;
&amp;lt;pre&amp;gt;dcs.advertiseURL=dcs.example.com:61616&amp;lt;/pre&amp;gt;&lt;br /&gt;
Additionally the address of the internal interface should resolved to the hostname; e.g. /etc/hosts reads like&lt;br /&gt;
&amp;lt;pre&amp;gt;192.168.10.25 dcs.example.com&amp;lt;/pre&amp;gt;&lt;br /&gt;
Especially on debian systems it might be necessary to modify /etc/hosts accordingly (and remove the 127.0.1.1 line).&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
The database schema for the DCS as well as appropriate database access data for the DCS user need to be created and set at the configured database prior to starting up the DCS for the first time. The database connection properties to be used by the DCS need to be set at the configuration file as well:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.host=192.168.10.172&lt;br /&gt;
db.port=3306&lt;br /&gt;
db.schema=dcsdb&lt;br /&gt;
db.username=db_user&lt;br /&gt;
db.password=db_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After setting these database related properties within the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file, the admin needs to call the &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh&amp;lt;/b&amp;gt; script as super user of the system. &lt;br /&gt;
&lt;br /&gt;
Database related settings made in the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file are read by this script first and taken as defaults. Nevertheless, each default value can be overwritten by the admin via the command line. Passwords need to be set by the admin via the command line in every case for security reasons.&lt;br /&gt;
&lt;br /&gt;
If all database properties have been set correctly within the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file, a valid call to the &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh&amp;lt;/b&amp;gt; script is e.g. the following one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo /usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh -a --dcsdb-pass=db_password --mysql-root-passwd=mysql_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The default logging path is set in &amp;lt;b&amp;gt;/etc/documents-collaboration/logback-spring.xml&amp;lt;/b&amp;gt; and points to &amp;lt;b&amp;gt;/var/log/open-xchange/documents-collaboration/documents-collaboration.log&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Documents Collaboration Service will be started by executing the following comand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl start open-xchange-documents-collaboration.service&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A command line tool allows to check the values in the database.&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
Before you can use this tool, you have to edit /opt/open-xchange/etc/documents-collaboration-client.properties in order to adapt it&lt;br /&gt;
to use the db username and password you configured above.&lt;br /&gt;
'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sudo /usr/share/open-xchange-documents-collaboration/bin/documents-collaboration-admin.sh -l&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| ID                  | Host          | Interface     | JMSPort |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| 192.168.10.25:61616 | 192.168.10.25 | 192.168.10.25 |   61616 |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
JMX access to the DCS can be enabled and configured in dcs.properties.&lt;br /&gt;
By default it is disabled. To enable JMX change the appropriate line to&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jmx.enabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Middleware node===&lt;br /&gt;
&lt;br /&gt;
No additional package repositories and no additional packages are required to be installed for the Middleware in order to use  DCS.&lt;br /&gt;
&lt;br /&gt;
Discovery of running DCSs via the database is configured in file &amp;lt;b&amp;gt;/opt/open-xchange/etc/documents-collaboration-client.properties&amp;lt;/b&amp;gt;.&lt;br /&gt;
Add the appropriate values to access the ''dcsdb'' Database as previously set during the DCS configuration (see above):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.openexchange.dcs.client.database.connectionURL=jdbc:mysql://192.168.10.172:3306/dcsdb&lt;br /&gt;
com.openexchange.dcs.client.database.userName=db_user&lt;br /&gt;
com.openexchange.dcs.client.database.password=db_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A command line tool allows to check the values in the database&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ /opt/open-xchange/sbin/documents-collaboration-admin -l&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| ID                  | Host          | Interface     | JMSPort |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| 192.168.10.25:61616 | 192.168.10.25 | 192.168.10.25 |   61616 |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Apache configuration===&lt;br /&gt;
&lt;br /&gt;
For working websocket support Apache version 2.4.10 or newer is required.&lt;br /&gt;
&lt;br /&gt;
The Apache module proxy_wstunnel has to be enabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo a2enmod proxy_wstunnel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the the following entries need to be added to the Apache configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Proxy balancer://oxcluster_ws&amp;gt;&lt;br /&gt;
  Order Deny,Allow&lt;br /&gt;
  Allow from all&lt;br /&gt;
  BalancerMember ws://localhost:8009 timeout=1900 smax=0 ttl=60 retry=60 loadfactor=50 keepalive=On route=OX1&lt;br /&gt;
  ProxySet stickysession=JSESSIONID|jsessionid scolonpathdelim=On&lt;br /&gt;
  SetEnv proxy-initial-not-pooled&lt;br /&gt;
  SetEnv proxy-sendchunked&lt;br /&gt;
&amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProxyPass /appsuite/rt2 balancer://oxcluster_ws/rt2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A running Apache server on the system needs to be restarted or triggered to reload its configuration after the above changes have been made.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
OX Documents offers runtime information via JMX about the document editors as well as the OX Documentconverter. This [[AppSuite:DocumentsMonitoring|article]] guides to the information how to access JMX data, configure and use Jolokia and integrate with munin.&lt;br /&gt;
&lt;br /&gt;
== Printing and legacy MS binary formats Editing ==&lt;br /&gt;
&lt;br /&gt;
For .DOC/.XLS/.PPT and/or printing support from OX Documents the Document Converter and readerengine components have to be installed separately (license key required)&lt;br /&gt;
&lt;br /&gt;
* See [[AppSuite:DocumentConverterInstall|Document converter / readerengine installation instructions]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
To enable the OX Documents Applications for OX Drive the associated permission has to be set.&lt;br /&gt;
&lt;br /&gt;
The default setting for all users is changed in the file '''documents.properties''' in the directory ''/opt/open-xchange/etc''.&lt;br /&gt;
&lt;br /&gt;
After installation the functionality is disabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Enables or disables the &amp;quot;text&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.text=true&lt;br /&gt;
&lt;br /&gt;
# Enables or disables the &amp;quot;spreadsheet&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.spreadsheet=true&lt;br /&gt;
&lt;br /&gt;
# Enables or disables the &amp;quot;presentation&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.presentation=true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following line enables the functionality:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Enables or disables the &amp;quot;text&amp;quot; module capability globally.&lt;br /&gt;
com.openexchange.capability.text=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starting with 7.6.2, you can disable the text portal app. In '''permissions.properties''':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
permissions=textportaldisabled&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collaboration on shared documents ===&lt;br /&gt;
&lt;br /&gt;
If OX Documents functionality is used for guest users in a cluster of application servers, this setting needs to be adjusted to false in order to also have guest sessions available in the distributed storage.&lt;br /&gt;
&lt;br /&gt;
in ''/opt/open-xchange/etc/sharing.properties'' &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Specifies whether guest sessions are treated as transient or not. Transient&lt;br /&gt;
# sessions are only held in the short-term session containers, and are not put&lt;br /&gt;
# into the distributed session storage. Defaults to &amp;quot;true&amp;quot;.&lt;br /&gt;
com.openexchange.share.transientSessions=false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
com.openechange.share.transientSessions has to be set to false.&lt;br /&gt;
&lt;br /&gt;
=== Spell Checking===&lt;br /&gt;
&lt;br /&gt;
OX Text and OX Presentation use ''hunspell'' for spell checking functionality.&lt;br /&gt;
By default Spellchecking is enabled in ''/opt/open-xchange/etc/settings/office.properties''&lt;br /&gt;
with the following entry&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines whether online spelling is enabled for office documents.&lt;br /&gt;
# Possible values: true|false&lt;br /&gt;
# If this property is missing true is taken.&lt;br /&gt;
io.ox/office//module/spellingEnabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installation of the ''hunspell'' package for your platform the shared library and the US English dictionaries are available. Please check the file location the pkg files were installed into. (For instance on CentOS, use rpm -q –filesbypkg hunspell and verify the path of the lib files to be configured below)&lt;br /&gt;
Also verify that the Hunspell dictonary is present and not renamed to &amp;quot;myspell&amp;quot; etc.. if the dictionary is renamed, you will have to use that in the config below. &lt;br /&gt;
&lt;br /&gt;
Additional dictionaries are published for your platform as packages hunspell-de-de,  hunspell-fr, ...&lt;br /&gt;
&lt;br /&gt;
Spell checking has to be configured in the file ''/opt/open-xchange/etc/hunspell.properties''.&lt;br /&gt;
The values for the shared library file and dictionary path have to be set according to the platform.&lt;br /&gt;
&lt;br /&gt;
This example shows the values for Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# The name and location of the hunspell library&lt;br /&gt;
# Default value: &amp;quot;/usr/lib/x86_64-linux-gnu/libhunspell-1.3.so.0&amp;quot;&lt;br /&gt;
com.openexchange.spellchecker.hunspell.library=/usr/lib/x86_64-linux-gnu/libhunspell-1.4.so.0&lt;br /&gt;
# The location of the dictionaries&lt;br /&gt;
# Default value: &amp;quot;/usr/share/hunspell&amp;quot;&lt;br /&gt;
com.openexchange.spellchecker.hunspell.dictionaries=/usr/share/hunspell&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If spellchecking is enabled and the library path or dictionary path is wrong a warning is logged.&lt;br /&gt;
&lt;br /&gt;
If a language is not supported by a hunspell dictionary (or produces error messages in the console log) myspell dictionaries are a working alternative.&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
OX Documents support different levels to provide document templates for users.&lt;br /&gt;
&lt;br /&gt;
A number of ready-to-use templates for letters, memos, resumes, home budget, presentations, etc is included with the system. These templates are made available in a directory at each system node by installation of the package open-xchange-documents-templates. The path to this directory is defined in the office.properties file &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Defines the absolute path where document templates are located inside the local (!) file system.&lt;br /&gt;
# The templates are displayed in the documents applications.&lt;br /&gt;
# If this property is missing a default '/opt/open-xchange/templates/documents' is taken.&lt;br /&gt;
io.ox/office//module/templatePath = /opt/open-xchange/templates/documents&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The content in the directory specified by the path must comply to the following rules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/open-xchange/templates/documents     &lt;br /&gt;
|     &lt;br /&gt;
----&amp;gt; text [application type]&lt;br /&gt;
|     |   &lt;br /&gt;
|     ----&amp;gt; en-US [language-region]&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; en [language fallback, en is also fallback for all other non-convered languages]&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; de-DE&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; de&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; common [language independent, used in addition to the language specific ones]&lt;br /&gt;
|         &lt;br /&gt;
----&amp;gt; spreadsheet&lt;br /&gt;
|         &lt;br /&gt;
----&amp;gt; presentation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A context administrator can additionally provide global templates for all users in the same context.&lt;br /&gt;
If logged in with this role folders can be added to or removed from the list of global template folders. For regular users the list is displayed without the permission to modify it.&lt;br /&gt;
&lt;br /&gt;
[[File:template-folder.png|border|600px|caption]]&lt;br /&gt;
&lt;br /&gt;
Users can create and manage their own templates. These user templates are stored and retrieved from the user’s root folder (“My files”). In addition to the root folder the user can define more template folders, sub-folders or even external folders in the “Documents” section of the “Settings” menu. This helps to organize templates and allows cleanup of the root folder by removal of templates.&lt;br /&gt;
&lt;br /&gt;
For installations of OX Spreadsheet based on Appsuite 7.8.0 and 7.8.1 please see [http://oxpedia.org/wiki/index.php?title=AppSuite:Spreadsheet_Installation_Guide_7_8_1 here] for different installation modes.&lt;br /&gt;
&lt;br /&gt;
=== OX Documents in Browser Tabs ===&lt;br /&gt;
&lt;br /&gt;
OX Documents based on Appsuite 7.10.2 opens new documents in new tabs in the browser by default.&lt;br /&gt;
&lt;br /&gt;
To disable this feature an stay in the single tab mode you have to set the attribute 'openInSingleTab' in as-config.yml&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Override certain settings&lt;br /&gt;
default:&lt;br /&gt;
    host: all&lt;br /&gt;
    openInSingleTab: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Documents_Installation_Guide&amp;diff=25209</id>
		<title>AppSuite:Documents Installation Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Documents_Installation_Guide&amp;diff=25209"/>
		<updated>2020-01-21T07:57:10Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Documents Collaboration Service (DCS) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.10.3}}&lt;br /&gt;
&lt;br /&gt;
For earlier versions see ''[[AppSuite:Documents_Installation_Guide_7.10.2_and_earlier|Guide for 7.10.2]]''&lt;br /&gt;
&lt;br /&gt;
= Download &amp;amp; Installation OX Documents =&lt;br /&gt;
&lt;br /&gt;
=== General Information ===&lt;br /&gt;
&lt;br /&gt;
OX Documents are browser based, cloud ready, text, spreadsheet and presentation products that can work with Microsoft Office and OpenOffice documents in a lossless way. And you can also collaborate with other people to edit shared documents on various devices.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
See the [[AppSuite:OX_System_Requirements|Open-Xchange software requirements page]] for details. Additionally the support of websockets proxy by the webserver or loadbalancer is required, this is e.g. available in Apache 2.4.10 and higher. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OX Documents needs to be installed in an OX App Suite configuration with a [[AppSuite:Grizzly|backend based on Grizzly]] (including hazelcast as installed and activated by default).&lt;br /&gt;
&lt;br /&gt;
For compatibility with the legacy MS binary format files (.DOC, .XLS, .PPT) and for printing functionality in OX Text the document converter components (incl. readerengine) are required. These are not available in the Community Version of OX AppSuite.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Mandatory Modules ==&lt;br /&gt;
&lt;br /&gt;
Additional functional modules need to be installed separately: &lt;br /&gt;
&lt;br /&gt;
* The Document Converter API: See [[AppSuite:DocumentConverterAPIInstall|Document converter API installation instructions]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
The OX Documents deployment consists of the packages &amp;lt;tt&amp;gt;open-xchange-documents-backend&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;open-xchange-documents-ui&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;open-xchange-documents-backend&amp;lt;/tt&amp;gt; package also requires and installs these packages:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-file-distribution&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-sessionstorage-hazelcast&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Packages are no longer needed since 7.10.3&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-realtime-core&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-realtime-json&amp;lt;/tt&amp;gt;&lt;br /&gt;
Furthermore all &amp;lt;tt&amp;gt;open-xchange-realtime-*&amp;lt;/tt&amp;gt; packages will be replaced with empty transitive packages to remove relicts of the realtime framework.&lt;br /&gt;
&lt;br /&gt;
The package &amp;lt;tt&amp;gt;open-xchange-documents-collaboration&amp;lt;/tt&amp;gt; has been introduced with 7.10.3. It provides the Documents Collaboration Service (see below).&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
 $ yum install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static documents-collaboration&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
The Apache version 2.2 provided with RHEL6 does not support websockets. &lt;br /&gt;
Please use Apache version 2.4.x available with RHSCL or any other capable loadbalancer.'''&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL7|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL7|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 9.0 (valid from v7.10) ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianStretch|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianStretch|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 10.0 (valid from v7.10.3) ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianBuster|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianBuster|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 === &lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Univention Corporate Server ===&lt;br /&gt;
&lt;br /&gt;
OX Text for OX App Suite for UCS is available in the Univention App Center. Please check the UMC module App Center for the installation of the OX Documents at your already available environment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Documents Collaboration Service ==&lt;br /&gt;
&lt;br /&gt;
Starting with release 7.10.3 the Documents Collaboration Service (DCS) has been introduced.&lt;br /&gt;
&lt;br /&gt;
The DCS needs to be installed, configured and run. It supports collaboration across Middleware nodes but is also mandatory for small (even single node) environments.&lt;br /&gt;
The server can be run as one additional service (JVM) or - for larger deployments - several instances can be clustered.&lt;br /&gt;
The implementation is based on Spring Boot and uses the Java-based messaging server Apache ActiveMQ.&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
For upgrades from earlier versions than 7.10.2 the hazelcast cluster requires a complete shutdown, since the internal OX Documents data has changed. A rolling upgrade is not possible.'''&lt;br /&gt;
&lt;br /&gt;
=== Documents Collaboration Service (DCS) ===&lt;br /&gt;
&lt;br /&gt;
Prepare documents-collaboration repository as described above.&lt;br /&gt;
&lt;br /&gt;
The DCS will be installed via the package:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
open-xchange-documents-collaboration&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The target directory is &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DCS configuration file is located at &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt;. All available configuration items are described on this [https://documentation.open-xchange.com/components/documents/documents-collaboration/config/7.10.3/#mode=features&amp;amp;feature=DocumentsCollaboration%20Server page]&lt;br /&gt;
&lt;br /&gt;
The following entries need to be reviewed and values need to be adjusted during the setup.&amp;lt;br&amp;gt;&lt;br /&gt;
Configure bind host IP and JMS Port to listen to&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dcs.host = 192.168.10.25       # Interface of the DCS node&lt;br /&gt;
dcs.port = 61616&lt;br /&gt;
&amp;lt;/pre&amp;gt;           &lt;br /&gt;
&lt;br /&gt;
A DCS writes its own connection data, retrieved from its configuration file during startup of the service, to a database to be discovered by Middleware nodes. &lt;br /&gt;
&lt;br /&gt;
'''Caveat:&amp;lt;/br&amp;gt;&lt;br /&gt;
In a distributed setup DCSs may be installed on separate nodes. If such a DCS node has different internal and external IP addresses one needs to make sure that a middleware node has the correct DCS address to connect to.&lt;br /&gt;
The config item &amp;lt;tt&amp;gt;advertiseURL&amp;lt;/tt&amp;gt; can be set to the name of the DCS node.&lt;br /&gt;
&amp;lt;pre&amp;gt;dcs.advertiseURL=dcs.example.com:61616&amp;lt;/pre&amp;gt;&lt;br /&gt;
Additionally the address of the internal interface should resolved to the hostname; e.g. /etc/hosts reads like&lt;br /&gt;
&amp;lt;pre&amp;gt;192.168.10.25 dcs.example.com&amp;lt;/pre&amp;gt;&lt;br /&gt;
Especially on debian systems it might be necessary to modify /etc/hosts accordingly (and remove the 127.0.1.1 line).&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
The database schema for the DCS as well as appropriate database access data for the DCS user need to be created and set at the configured database prior to starting up the DCS for the first time. The database connection properties to be used by the DCS need to be set at the configuration file as well:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.host=192.168.10.172&lt;br /&gt;
db.port=3306&lt;br /&gt;
db.schema=dcsdb&lt;br /&gt;
db.username=db_user&lt;br /&gt;
db.password=db_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After setting these database related properties within the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file, the admin needs to call the &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh&amp;lt;/b&amp;gt; script as super user of the system. &lt;br /&gt;
&lt;br /&gt;
Database related settings made in the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file are read by this script first and taken as defaults. Nevertheless, each default value can be overwritten by the admin via the command line. Passwords need to be set by the admin via the command line in every case for security reasons.&lt;br /&gt;
&lt;br /&gt;
If all database properties have been set correctly within the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file, a valid call to the &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh&amp;lt;/b&amp;gt; script is e.g. the following one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo /usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh -a --dcsdb-pass=db_password --mysql-root-passwd=mysql_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The default logging path is set in &amp;lt;b&amp;gt;/etc/documents-collaboration/logback-spring.xml&amp;lt;/b&amp;gt; and points to &amp;lt;b&amp;gt;/var/log/open-xchange/documents-collaboration/documents-collaboration.log&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Documents Collaboration Service will be started by executing the following comand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl start open-xchange-documents-collaboration.service&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A command line tool allows to check the values in the database.&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
Before you can use this tool, you have to edit /opt/open-xchange/etc/documents-collaboration-client.properties in order to adapt it&lt;br /&gt;
to use the db username and password you configured above.&lt;br /&gt;
'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sudo /usr/share/open-xchange-documents-collaboration/bin/documents-collaboration-admin.sh -l&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| ID                  | Host          | Interface     | JMSPort |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| 192.168.10.25:61616 | 192.168.10.25 | 192.168.10.25 |   61616 |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
JMX access to the DCS can be enabled and configured in dcs.properties.&lt;br /&gt;
By default it is disabled. To enable JMX change the appropriate line to&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jmx.enabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Middleware node===&lt;br /&gt;
&lt;br /&gt;
No additional package repositories and no additional packages are required to be installed for the Middleware in order to use  DCS.&lt;br /&gt;
&lt;br /&gt;
Discovery of running DCSs via the database is configured in file &amp;lt;b&amp;gt;/opt/open-xchange/etc/documents-collaboration-client.properties&amp;lt;/b&amp;gt;.&lt;br /&gt;
Add the appropriate values to access the ''dcsdb'' Database as previously set during the DCS configuration (see above):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.openexchange.dcs.client.database.connectionURL=jdbc:mysql://192.168.10.172:3306/dcsdb&lt;br /&gt;
com.openexchange.dcs.client.database.userName=db_user&lt;br /&gt;
com.openexchange.dcs.client.database.password=db_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A command line tool allows to check the values in the database&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ /opt/open-xchange/sbin/documents-collaboration-admin -l&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| ID                  | Host          | Interface     | JMSPort |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| 192.168.10.25:61616 | 192.168.10.25 | 192.168.10.25 |   61616 |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Apache configuration===&lt;br /&gt;
&lt;br /&gt;
For working websocket support Apache version 2.4.10 or newer is required.&lt;br /&gt;
&lt;br /&gt;
The Apache module proxy_wstunnel has to be enabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a2enmod proxy_wstunnel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the the following entries need to be added to the Apache configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Proxy balancer://oxcluster_ws&amp;gt;&lt;br /&gt;
  Order Deny,Allow&lt;br /&gt;
  Allow from all&lt;br /&gt;
  BalancerMember ws://localhost:8009 timeout=1900 smax=0 ttl=60 retry=60 loadfactor=50 keepalive=On route=OX1&lt;br /&gt;
  ProxySet stickysession=JSESSIONID|jsessionid scolonpathdelim=On&lt;br /&gt;
  SetEnv proxy-initial-not-pooled&lt;br /&gt;
  SetEnv proxy-sendchunked&lt;br /&gt;
&amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProxyPass /appsuite/rt2 balancer://oxcluster_ws/rt2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A running Apache server on the system needs to be restarted or triggered to reload its configuration after the above changes have been made.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
OX Documents offers runtime information via JMX about the document editors as well as the OX Documentconverter. This [[AppSuite:DocumentsMonitoring|article]] guides to the information how to access JMX data, configure and use Jolokia and integrate with munin.&lt;br /&gt;
&lt;br /&gt;
== Printing and legacy MS binary formats Editing ==&lt;br /&gt;
&lt;br /&gt;
For .DOC/.XLS/.PPT and/or printing support from OX Documents the Document Converter and readerengine components have to be installed separately (license key required)&lt;br /&gt;
&lt;br /&gt;
* See [[AppSuite:DocumentConverterInstall|Document converter / readerengine installation instructions]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
To enable the OX Documents Applications for OX Drive the associated permission has to be set.&lt;br /&gt;
&lt;br /&gt;
The default setting for all users is changed in the file '''documents.properties''' in the directory ''/opt/open-xchange/etc''.&lt;br /&gt;
&lt;br /&gt;
After installation the functionality is disabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Enables or disables the &amp;quot;text&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.text=true&lt;br /&gt;
&lt;br /&gt;
# Enables or disables the &amp;quot;spreadsheet&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.spreadsheet=true&lt;br /&gt;
&lt;br /&gt;
# Enables or disables the &amp;quot;presentation&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.presentation=true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following line enables the functionality:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Enables or disables the &amp;quot;text&amp;quot; module capability globally.&lt;br /&gt;
com.openexchange.capability.text=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starting with 7.6.2, you can disable the text portal app. In '''permissions.properties''':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
permissions=textportaldisabled&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collaboration on shared documents ===&lt;br /&gt;
&lt;br /&gt;
If OX Documents functionality is used for guest users in a cluster of application servers, this setting needs to be adjusted to false in order to also have guest sessions available in the distributed storage.&lt;br /&gt;
&lt;br /&gt;
in ''/opt/open-xchange/etc/sharing.properties'' &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Specifies whether guest sessions are treated as transient or not. Transient&lt;br /&gt;
# sessions are only held in the short-term session containers, and are not put&lt;br /&gt;
# into the distributed session storage. Defaults to &amp;quot;true&amp;quot;.&lt;br /&gt;
com.openexchange.share.transientSessions=false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
com.openechange.share.transientSessions has to be set to false.&lt;br /&gt;
&lt;br /&gt;
=== Spell Checking===&lt;br /&gt;
&lt;br /&gt;
OX Text and OX Presentation use ''hunspell'' for spell checking functionality.&lt;br /&gt;
By default Spellchecking is enabled in ''/opt/open-xchange/etc/settings/office.properties''&lt;br /&gt;
with the following entry&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines whether online spelling is enabled for office documents.&lt;br /&gt;
# Possible values: true|false&lt;br /&gt;
# If this property is missing true is taken.&lt;br /&gt;
io.ox/office//module/spellingEnabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installation of the ''hunspell'' package for your platform the shared library and the US English dictionaries are available. Please check the file location the pkg files were installed into. (For instance on CentOS, use rpm -q –filesbypkg hunspell and verify the path of the lib files to be configured below)&lt;br /&gt;
Also verify that the Hunspell dictonary is present and not renamed to &amp;quot;myspell&amp;quot; etc.. if the dictionary is renamed, you will have to use that in the config below. &lt;br /&gt;
&lt;br /&gt;
Additional dictionaries are published for your platform as packages hunspell-de-de,  hunspell-fr, ...&lt;br /&gt;
&lt;br /&gt;
Spell checking has to be configured in the file ''/opt/open-xchange/etc/hunspell.properties''.&lt;br /&gt;
The values for the shared library file and dictionary path have to be set according to the platform.&lt;br /&gt;
&lt;br /&gt;
This example shows the values for Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# The name and location of the hunspell library&lt;br /&gt;
# Default value: &amp;quot;/usr/lib/x86_64-linux-gnu/libhunspell-1.3.so.0&amp;quot;&lt;br /&gt;
com.openexchange.spellchecker.hunspell.library=/usr/lib/x86_64-linux-gnu/libhunspell-1.4.so.0&lt;br /&gt;
# The location of the dictionaries&lt;br /&gt;
# Default value: &amp;quot;/usr/share/hunspell&amp;quot;&lt;br /&gt;
com.openexchange.spellchecker.hunspell.dictionaries=/usr/share/hunspell&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If spellchecking is enabled and the library path or dictionary path is wrong a warning is logged.&lt;br /&gt;
&lt;br /&gt;
If a language is not supported by a hunspell dictionary (or produces error messages in the console log) myspell dictionaries are a working alternative.&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
OX Documents support different levels to provide document templates for users.&lt;br /&gt;
&lt;br /&gt;
A number of ready-to-use templates for letters, memos, resumes, home budget, presentations, etc is included with the system. These templates are made available in a directory at each system node by installation of the package open-xchange-documents-templates. The path to this directory is defined in the office.properties file &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Defines the absolute path where document templates are located inside the local (!) file system.&lt;br /&gt;
# The templates are displayed in the documents applications.&lt;br /&gt;
# If this property is missing a default '/opt/open-xchange/templates/documents' is taken.&lt;br /&gt;
io.ox/office//module/templatePath = /opt/open-xchange/templates/documents&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The content in the directory specified by the path must comply to the following rules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/open-xchange/templates/documents     &lt;br /&gt;
|     &lt;br /&gt;
----&amp;gt; text [application type]&lt;br /&gt;
|     |   &lt;br /&gt;
|     ----&amp;gt; en-US [language-region]&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; en [language fallback, en is also fallback for all other non-convered languages]&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; de-DE&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; de&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; common [language independent, used in addition to the language specific ones]&lt;br /&gt;
|         &lt;br /&gt;
----&amp;gt; spreadsheet&lt;br /&gt;
|         &lt;br /&gt;
----&amp;gt; presentation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A context administrator can additionally provide global templates for all users in the same context.&lt;br /&gt;
If logged in with this role folders can be added to or removed from the list of global template folders. For regular users the list is displayed without the permission to modify it.&lt;br /&gt;
&lt;br /&gt;
[[File:template-folder.png|border|600px|caption]]&lt;br /&gt;
&lt;br /&gt;
Users can create and manage their own templates. These user templates are stored and retrieved from the user’s root folder (“My files”). In addition to the root folder the user can define more template folders, sub-folders or even external folders in the “Documents” section of the “Settings” menu. This helps to organize templates and allows cleanup of the root folder by removal of templates.&lt;br /&gt;
&lt;br /&gt;
For installations of OX Spreadsheet based on Appsuite 7.8.0 and 7.8.1 please see [http://oxpedia.org/wiki/index.php?title=AppSuite:Spreadsheet_Installation_Guide_7_8_1 here] for different installation modes.&lt;br /&gt;
&lt;br /&gt;
=== OX Documents in Browser Tabs ===&lt;br /&gt;
&lt;br /&gt;
OX Documents based on Appsuite 7.10.2 opens new documents in new tabs in the browser by default.&lt;br /&gt;
&lt;br /&gt;
To disable this feature an stay in the single tab mode you have to set the attribute 'openInSingleTab' in as-config.yml&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Override certain settings&lt;br /&gt;
default:&lt;br /&gt;
    host: all&lt;br /&gt;
    openInSingleTab: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Documents_Installation_Guide&amp;diff=25208</id>
		<title>AppSuite:Documents Installation Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Documents_Installation_Guide&amp;diff=25208"/>
		<updated>2020-01-21T07:53:03Z</updated>

		<summary type="html">&lt;p&gt;Choeger: either sudo or not sudo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.10.3}}&lt;br /&gt;
&lt;br /&gt;
For earlier versions see ''[[AppSuite:Documents_Installation_Guide_7.10.2_and_earlier|Guide for 7.10.2]]''&lt;br /&gt;
&lt;br /&gt;
= Download &amp;amp; Installation OX Documents =&lt;br /&gt;
&lt;br /&gt;
=== General Information ===&lt;br /&gt;
&lt;br /&gt;
OX Documents are browser based, cloud ready, text, spreadsheet and presentation products that can work with Microsoft Office and OpenOffice documents in a lossless way. And you can also collaborate with other people to edit shared documents on various devices.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
See the [[AppSuite:OX_System_Requirements|Open-Xchange software requirements page]] for details. Additionally the support of websockets proxy by the webserver or loadbalancer is required, this is e.g. available in Apache 2.4.10 and higher. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OX Documents needs to be installed in an OX App Suite configuration with a [[AppSuite:Grizzly|backend based on Grizzly]] (including hazelcast as installed and activated by default).&lt;br /&gt;
&lt;br /&gt;
For compatibility with the legacy MS binary format files (.DOC, .XLS, .PPT) and for printing functionality in OX Text the document converter components (incl. readerengine) are required. These are not available in the Community Version of OX AppSuite.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Mandatory Modules ==&lt;br /&gt;
&lt;br /&gt;
Additional functional modules need to be installed separately: &lt;br /&gt;
&lt;br /&gt;
* The Document Converter API: See [[AppSuite:DocumentConverterAPIInstall|Document converter API installation instructions]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
The OX Documents deployment consists of the packages &amp;lt;tt&amp;gt;open-xchange-documents-backend&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;open-xchange-documents-ui&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;open-xchange-documents-backend&amp;lt;/tt&amp;gt; package also requires and installs these packages:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-file-distribution&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-sessionstorage-hazelcast&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Packages are no longer needed since 7.10.3&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-realtime-core&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-realtime-json&amp;lt;/tt&amp;gt;&lt;br /&gt;
Furthermore all &amp;lt;tt&amp;gt;open-xchange-realtime-*&amp;lt;/tt&amp;gt; packages will be replaced with empty transitive packages to remove relicts of the realtime framework.&lt;br /&gt;
&lt;br /&gt;
The package &amp;lt;tt&amp;gt;open-xchange-documents-collaboration&amp;lt;/tt&amp;gt; has been introduced with 7.10.3. It provides the Documents Collaboration Service (see below).&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
 $ yum install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static documents-collaboration&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
The Apache version 2.2 provided with RHEL6 does not support websockets. &lt;br /&gt;
Please use Apache version 2.4.x available with RHSCL or any other capable loadbalancer.'''&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL7|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL7|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 9.0 (valid from v7.10) ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianStretch|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianStretch|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 10.0 (valid from v7.10.3) ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianBuster|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianBuster|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 === &lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Univention Corporate Server ===&lt;br /&gt;
&lt;br /&gt;
OX Text for OX App Suite for UCS is available in the Univention App Center. Please check the UMC module App Center for the installation of the OX Documents at your already available environment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Documents Collaboration Service ==&lt;br /&gt;
&lt;br /&gt;
Starting with release 7.10.3 the Documents Collaboration Service (DCS) has been introduced.&lt;br /&gt;
&lt;br /&gt;
The DCS needs to be installed, configured and run. It supports collaboration across Middleware nodes but is also mandatory for small (even single node) environments.&lt;br /&gt;
The server can be run as one additional service (JVM) or - for larger deployments - several instances can be clustered.&lt;br /&gt;
The implementation is based on Spring Boot and uses the Java-based messaging server Apache ActiveMQ.&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
For upgrades from earlier versions than 7.10.2 the hazelcast cluster requires a complete shutdown, since the internal OX Documents data has changed. A rolling upgrade is not possible.'''&lt;br /&gt;
&lt;br /&gt;
=== Documents Collaboration Service (DCS) ===&lt;br /&gt;
&lt;br /&gt;
Prepare documents-collaboration repository as described above.&lt;br /&gt;
&lt;br /&gt;
The DCS will be installed via the package:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
open-xchange-documents-collaboration&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The target directory is &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DCS configuration file is located at &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt;. All available configuration items are described on this [https://documentation.open-xchange.com/components/documents/documents-collaboration/config/7.10.3/#mode=features&amp;amp;feature=DocumentsCollaboration%20Server page]&lt;br /&gt;
&lt;br /&gt;
The following entries need to be reviewed and values need to be adjusted during the setup.&amp;lt;br&amp;gt;&lt;br /&gt;
Configure bind host IP and JMS Port to listen to&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dcs.host = 192.168.10.25       # Interface of the DCS node&lt;br /&gt;
dcs.port = 61616&lt;br /&gt;
&amp;lt;/pre&amp;gt;           &lt;br /&gt;
&lt;br /&gt;
A DCS writes its own connection data, retrieved from its configuration file during startup of the service, to a database to be discovered by Middleware nodes. &lt;br /&gt;
&lt;br /&gt;
'''Caveat:&amp;lt;/br&amp;gt;&lt;br /&gt;
In a distributed setup DCSs may be installed on separate nodes. If such a DCS node has different internal and external IP addresses one needs to make sure that a middleware node has the correct DCS address to connect to.&lt;br /&gt;
The config item &amp;lt;tt&amp;gt;advertiseURL&amp;lt;/tt&amp;gt; can be set to the name of the DCS node.&lt;br /&gt;
&amp;lt;pre&amp;gt;dcs.advertiseURL=dcs.example.com:61616&amp;lt;/pre&amp;gt;&lt;br /&gt;
Additionally the address of the internal interface should resolved to the hostname; e.g. /etc/hosts reads like&lt;br /&gt;
&amp;lt;pre&amp;gt;192.168.10.25 dcs.example.com&amp;lt;/pre&amp;gt;&lt;br /&gt;
Especially on debian systems it might be necessary to modify /etc/hosts accordingly (and remove the 127.0.1.1 line).&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
The database schema for the DCS as well as appropriate database access data for the DCS user need to be created and set at the configured database prior to starting up the DCS for the first time. The database connection properties to be used by the DCS need to be set at the configuration file as well:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.host=192.168.10.172&lt;br /&gt;
db.port=3306&lt;br /&gt;
db.schema=dcsdb&lt;br /&gt;
db.username=db_user&lt;br /&gt;
db.password=db_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After setting these database related properties within the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file, the admin needs to call the &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh&amp;lt;/b&amp;gt; script as super user of the system. &lt;br /&gt;
&lt;br /&gt;
Database related settings made in the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file are read by this script first and taken as defaults. Nevertheless, each default value can be overwritten by the admin via the command line. Passwords need to be set by the admin via the command line in every case for security reasons.&lt;br /&gt;
&lt;br /&gt;
If all database properties have been set correctly within the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file, a valid call to the &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh&amp;lt;/b&amp;gt; script is e.g. the following one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo /usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh -a --dcsdb-pass=db_password --mysql-root-passwd=mysql_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The default logging path is set in &amp;lt;b&amp;gt;/etc/documents-collaboration/logback-spring.xml&amp;lt;/b&amp;gt; and points to &amp;lt;b&amp;gt;/var/log/open-xchange/documents-collaboration/documents-collaboration.log&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Documents Collaboration Service will be started by executing the following comand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl start open-xchange-documents-collaboration.service&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A command line tool allows to check the values in the database&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# sudo /usr/share/open-xchange-documents-collaboration/bin/documents-collaboration-admin.sh -l&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| ID                  | Host          | Interface     | JMSPort |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| 192.168.10.25:61616 | 192.168.10.25 | 192.168.10.25 |   61616 |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
JMX access to the DCS can be enabled and configured in dcs.properties.&lt;br /&gt;
By default it is disabled. To enable JMX change the appropriate line to&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jmx.enabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Middleware node===&lt;br /&gt;
&lt;br /&gt;
No additional package repositories and no additional packages are required to be installed for the Middleware in order to use  DCS.&lt;br /&gt;
&lt;br /&gt;
Discovery of running DCSs via the database is configured in file &amp;lt;b&amp;gt;/opt/open-xchange/etc/documents-collaboration-client.properties&amp;lt;/b&amp;gt;.&lt;br /&gt;
Add the appropriate values to access the ''dcsdb'' Database as previously set during the DCS configuration (see above):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.openexchange.dcs.client.database.connectionURL=jdbc:mysql://192.168.10.172:3306/dcsdb&lt;br /&gt;
com.openexchange.dcs.client.database.userName=db_user&lt;br /&gt;
com.openexchange.dcs.client.database.password=db_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A command line tool allows to check the values in the database&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ /opt/open-xchange/sbin/documents-collaboration-admin -l&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| ID                  | Host          | Interface     | JMSPort |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| 192.168.10.25:61616 | 192.168.10.25 | 192.168.10.25 |   61616 |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Apache configuration===&lt;br /&gt;
&lt;br /&gt;
For working websocket support Apache version 2.4.10 or newer is required.&lt;br /&gt;
&lt;br /&gt;
The Apache module proxy_wstunnel has to be enabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a2enmod proxy_wstunnel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the the following entries need to be added to the Apache configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Proxy balancer://oxcluster_ws&amp;gt;&lt;br /&gt;
  Order Deny,Allow&lt;br /&gt;
  Allow from all&lt;br /&gt;
  BalancerMember ws://localhost:8009 timeout=1900 smax=0 ttl=60 retry=60 loadfactor=50 keepalive=On route=OX1&lt;br /&gt;
  ProxySet stickysession=JSESSIONID|jsessionid scolonpathdelim=On&lt;br /&gt;
  SetEnv proxy-initial-not-pooled&lt;br /&gt;
  SetEnv proxy-sendchunked&lt;br /&gt;
&amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProxyPass /appsuite/rt2 balancer://oxcluster_ws/rt2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A running Apache server on the system needs to be restarted or triggered to reload its configuration after the above changes have been made.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
OX Documents offers runtime information via JMX about the document editors as well as the OX Documentconverter. This [[AppSuite:DocumentsMonitoring|article]] guides to the information how to access JMX data, configure and use Jolokia and integrate with munin.&lt;br /&gt;
&lt;br /&gt;
== Printing and legacy MS binary formats Editing ==&lt;br /&gt;
&lt;br /&gt;
For .DOC/.XLS/.PPT and/or printing support from OX Documents the Document Converter and readerengine components have to be installed separately (license key required)&lt;br /&gt;
&lt;br /&gt;
* See [[AppSuite:DocumentConverterInstall|Document converter / readerengine installation instructions]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
To enable the OX Documents Applications for OX Drive the associated permission has to be set.&lt;br /&gt;
&lt;br /&gt;
The default setting for all users is changed in the file '''documents.properties''' in the directory ''/opt/open-xchange/etc''.&lt;br /&gt;
&lt;br /&gt;
After installation the functionality is disabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Enables or disables the &amp;quot;text&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.text=true&lt;br /&gt;
&lt;br /&gt;
# Enables or disables the &amp;quot;spreadsheet&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.spreadsheet=true&lt;br /&gt;
&lt;br /&gt;
# Enables or disables the &amp;quot;presentation&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.presentation=true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following line enables the functionality:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Enables or disables the &amp;quot;text&amp;quot; module capability globally.&lt;br /&gt;
com.openexchange.capability.text=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starting with 7.6.2, you can disable the text portal app. In '''permissions.properties''':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
permissions=textportaldisabled&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collaboration on shared documents ===&lt;br /&gt;
&lt;br /&gt;
If OX Documents functionality is used for guest users in a cluster of application servers, this setting needs to be adjusted to false in order to also have guest sessions available in the distributed storage.&lt;br /&gt;
&lt;br /&gt;
in ''/opt/open-xchange/etc/sharing.properties'' &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Specifies whether guest sessions are treated as transient or not. Transient&lt;br /&gt;
# sessions are only held in the short-term session containers, and are not put&lt;br /&gt;
# into the distributed session storage. Defaults to &amp;quot;true&amp;quot;.&lt;br /&gt;
com.openexchange.share.transientSessions=false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
com.openechange.share.transientSessions has to be set to false.&lt;br /&gt;
&lt;br /&gt;
=== Spell Checking===&lt;br /&gt;
&lt;br /&gt;
OX Text and OX Presentation use ''hunspell'' for spell checking functionality.&lt;br /&gt;
By default Spellchecking is enabled in ''/opt/open-xchange/etc/settings/office.properties''&lt;br /&gt;
with the following entry&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines whether online spelling is enabled for office documents.&lt;br /&gt;
# Possible values: true|false&lt;br /&gt;
# If this property is missing true is taken.&lt;br /&gt;
io.ox/office//module/spellingEnabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installation of the ''hunspell'' package for your platform the shared library and the US English dictionaries are available. Please check the file location the pkg files were installed into. (For instance on CentOS, use rpm -q –filesbypkg hunspell and verify the path of the lib files to be configured below)&lt;br /&gt;
Also verify that the Hunspell dictonary is present and not renamed to &amp;quot;myspell&amp;quot; etc.. if the dictionary is renamed, you will have to use that in the config below. &lt;br /&gt;
&lt;br /&gt;
Additional dictionaries are published for your platform as packages hunspell-de-de,  hunspell-fr, ...&lt;br /&gt;
&lt;br /&gt;
Spell checking has to be configured in the file ''/opt/open-xchange/etc/hunspell.properties''.&lt;br /&gt;
The values for the shared library file and dictionary path have to be set according to the platform.&lt;br /&gt;
&lt;br /&gt;
This example shows the values for Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# The name and location of the hunspell library&lt;br /&gt;
# Default value: &amp;quot;/usr/lib/x86_64-linux-gnu/libhunspell-1.3.so.0&amp;quot;&lt;br /&gt;
com.openexchange.spellchecker.hunspell.library=/usr/lib/x86_64-linux-gnu/libhunspell-1.4.so.0&lt;br /&gt;
# The location of the dictionaries&lt;br /&gt;
# Default value: &amp;quot;/usr/share/hunspell&amp;quot;&lt;br /&gt;
com.openexchange.spellchecker.hunspell.dictionaries=/usr/share/hunspell&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If spellchecking is enabled and the library path or dictionary path is wrong a warning is logged.&lt;br /&gt;
&lt;br /&gt;
If a language is not supported by a hunspell dictionary (or produces error messages in the console log) myspell dictionaries are a working alternative.&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
OX Documents support different levels to provide document templates for users.&lt;br /&gt;
&lt;br /&gt;
A number of ready-to-use templates for letters, memos, resumes, home budget, presentations, etc is included with the system. These templates are made available in a directory at each system node by installation of the package open-xchange-documents-templates. The path to this directory is defined in the office.properties file &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Defines the absolute path where document templates are located inside the local (!) file system.&lt;br /&gt;
# The templates are displayed in the documents applications.&lt;br /&gt;
# If this property is missing a default '/opt/open-xchange/templates/documents' is taken.&lt;br /&gt;
io.ox/office//module/templatePath = /opt/open-xchange/templates/documents&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The content in the directory specified by the path must comply to the following rules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/open-xchange/templates/documents     &lt;br /&gt;
|     &lt;br /&gt;
----&amp;gt; text [application type]&lt;br /&gt;
|     |   &lt;br /&gt;
|     ----&amp;gt; en-US [language-region]&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; en [language fallback, en is also fallback for all other non-convered languages]&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; de-DE&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; de&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; common [language independent, used in addition to the language specific ones]&lt;br /&gt;
|         &lt;br /&gt;
----&amp;gt; spreadsheet&lt;br /&gt;
|         &lt;br /&gt;
----&amp;gt; presentation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A context administrator can additionally provide global templates for all users in the same context.&lt;br /&gt;
If logged in with this role folders can be added to or removed from the list of global template folders. For regular users the list is displayed without the permission to modify it.&lt;br /&gt;
&lt;br /&gt;
[[File:template-folder.png|border|600px|caption]]&lt;br /&gt;
&lt;br /&gt;
Users can create and manage their own templates. These user templates are stored and retrieved from the user’s root folder (“My files”). In addition to the root folder the user can define more template folders, sub-folders or even external folders in the “Documents” section of the “Settings” menu. This helps to organize templates and allows cleanup of the root folder by removal of templates.&lt;br /&gt;
&lt;br /&gt;
For installations of OX Spreadsheet based on Appsuite 7.8.0 and 7.8.1 please see [http://oxpedia.org/wiki/index.php?title=AppSuite:Spreadsheet_Installation_Guide_7_8_1 here] for different installation modes.&lt;br /&gt;
&lt;br /&gt;
=== OX Documents in Browser Tabs ===&lt;br /&gt;
&lt;br /&gt;
OX Documents based on Appsuite 7.10.2 opens new documents in new tabs in the browser by default.&lt;br /&gt;
&lt;br /&gt;
To disable this feature an stay in the single tab mode you have to set the attribute 'openInSingleTab' in as-config.yml&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Override certain settings&lt;br /&gt;
default:&lt;br /&gt;
    host: all&lt;br /&gt;
    openInSingleTab: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Documents_Installation_Guide&amp;diff=25207</id>
		<title>AppSuite:Documents Installation Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Documents_Installation_Guide&amp;diff=25207"/>
		<updated>2020-01-21T07:49:49Z</updated>

		<summary type="html">&lt;p&gt;Choeger: either sudo or not sudo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.10.3}}&lt;br /&gt;
&lt;br /&gt;
For earlier versions see ''[[AppSuite:Documents_Installation_Guide_7.10.2_and_earlier|Guide for 7.10.2]]''&lt;br /&gt;
&lt;br /&gt;
= Download &amp;amp; Installation OX Documents =&lt;br /&gt;
&lt;br /&gt;
=== General Information ===&lt;br /&gt;
&lt;br /&gt;
OX Documents are browser based, cloud ready, text, spreadsheet and presentation products that can work with Microsoft Office and OpenOffice documents in a lossless way. And you can also collaborate with other people to edit shared documents on various devices.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
See the [[AppSuite:OX_System_Requirements|Open-Xchange software requirements page]] for details. Additionally the support of websockets proxy by the webserver or loadbalancer is required, this is e.g. available in Apache 2.4.10 and higher. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OX Documents needs to be installed in an OX App Suite configuration with a [[AppSuite:Grizzly|backend based on Grizzly]] (including hazelcast as installed and activated by default).&lt;br /&gt;
&lt;br /&gt;
For compatibility with the legacy MS binary format files (.DOC, .XLS, .PPT) and for printing functionality in OX Text the document converter components (incl. readerengine) are required. These are not available in the Community Version of OX AppSuite.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Mandatory Modules ==&lt;br /&gt;
&lt;br /&gt;
Additional functional modules need to be installed separately: &lt;br /&gt;
&lt;br /&gt;
* The Document Converter API: See [[AppSuite:DocumentConverterAPIInstall|Document converter API installation instructions]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
The OX Documents deployment consists of the packages &amp;lt;tt&amp;gt;open-xchange-documents-backend&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;open-xchange-documents-ui&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;open-xchange-documents-backend&amp;lt;/tt&amp;gt; package also requires and installs these packages:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-file-distribution&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-sessionstorage-hazelcast&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following Packages are no longer needed since 7.10.3&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-realtime-core&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;open-xchange-realtime-json&amp;lt;/tt&amp;gt;&lt;br /&gt;
Furthermore all &amp;lt;tt&amp;gt;open-xchange-realtime-*&amp;lt;/tt&amp;gt; packages will be replaced with empty transitive packages to remove relicts of the realtime framework.&lt;br /&gt;
&lt;br /&gt;
The package &amp;lt;tt&amp;gt;open-xchange-documents-collaboration&amp;lt;/tt&amp;gt; has been introduced with 7.10.3. It provides the Documents Collaboration Service (see below).&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
 $ yum install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static documents-collaboration&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
The Apache version 2.2 provided with RHEL6 does not support websockets. &lt;br /&gt;
Please use Apache version 2.4.x available with RHSCL or any other capable loadbalancer.'''&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL7|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL7|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 9.0 (valid from v7.10) ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianStretch|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianStretch|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 10.0 (valid from v7.10.3) ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianBuster|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianBuster|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration/updates}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 === &lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|office|office-web|documentconverter-api|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
if you have a valid maintenance subscription, please add also following repositories by replacing the credentials.&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|office/updates|office-web/updates|documentconverter-api/updates|documents-collaboration}}&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper install open-xchange-documents-backend open-xchange-documents-ui open-xchange-documents-ui-static open-xchange-documents-collaboration&lt;br /&gt;
&lt;br /&gt;
=== Univention Corporate Server ===&lt;br /&gt;
&lt;br /&gt;
OX Text for OX App Suite for UCS is available in the Univention App Center. Please check the UMC module App Center for the installation of the OX Documents at your already available environment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Documents Collaboration Service ==&lt;br /&gt;
&lt;br /&gt;
Starting with release 7.10.3 the Documents Collaboration Service (DCS) has been introduced.&lt;br /&gt;
&lt;br /&gt;
The DCS needs to be installed, configured and run. It supports collaboration across Middleware nodes but is also mandatory for small (even single node) environments.&lt;br /&gt;
The server can be run as one additional service (JVM) or - for larger deployments - several instances can be clustered.&lt;br /&gt;
The implementation is based on Spring Boot and uses the Java-based messaging server Apache ActiveMQ.&lt;br /&gt;
&lt;br /&gt;
'''Note:&amp;lt;/br&amp;gt;&lt;br /&gt;
For upgrades from earlier versions than 7.10.2 the hazelcast cluster requires a complete shutdown, since the internal OX Documents data has changed. A rolling upgrade is not possible.'''&lt;br /&gt;
&lt;br /&gt;
=== Documents Collaboration Service (DCS) ===&lt;br /&gt;
&lt;br /&gt;
Prepare documents-collaboration repository as described above.&lt;br /&gt;
&lt;br /&gt;
The DCS will be installed via the package:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
open-xchange-documents-collaboration&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The target directory is &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DCS configuration file is located at &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt;. All available configuration items are described on this [https://documentation.open-xchange.com/components/documents/documents-collaboration/config/7.10.3/#mode=features&amp;amp;feature=DocumentsCollaboration%20Server page]&lt;br /&gt;
&lt;br /&gt;
The following entries need to be reviewed and values need to be adjusted during the setup.&amp;lt;br&amp;gt;&lt;br /&gt;
Configure bind host IP and JMS Port to listen to&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dcs.host = 192.168.10.25       # Interface of the DCS node&lt;br /&gt;
dcs.port = 61616&lt;br /&gt;
&amp;lt;/pre&amp;gt;           &lt;br /&gt;
&lt;br /&gt;
A DCS writes its own connection data, retrieved from its configuration file during startup of the service, to a database to be discovered by Middleware nodes. &lt;br /&gt;
&lt;br /&gt;
'''Caveat:&amp;lt;/br&amp;gt;&lt;br /&gt;
In a distributed setup DCSs may be installed on separate nodes. If such a DCS node has different internal and external IP addresses one needs to make sure that a middleware node has the correct DCS address to connect to.&lt;br /&gt;
The config item &amp;lt;tt&amp;gt;advertiseURL&amp;lt;/tt&amp;gt; can be set to the name of the DCS node.&lt;br /&gt;
&amp;lt;pre&amp;gt;dcs.advertiseURL=dcs.example.com:61616&amp;lt;/pre&amp;gt;&lt;br /&gt;
Additionally the address of the internal interface should resolved to the hostname; e.g. /etc/hosts reads like&lt;br /&gt;
&amp;lt;pre&amp;gt;192.168.10.25 dcs.example.com&amp;lt;/pre&amp;gt;&lt;br /&gt;
Especially on debian systems it might be necessary to modify /etc/hosts accordingly (and remove the 127.0.1.1 line).&lt;br /&gt;
'''&lt;br /&gt;
&lt;br /&gt;
The database schema for the DCS as well as appropriate database access data for the DCS user need to be created and set at the configured database prior to starting up the DCS for the first time. The database connection properties to be used by the DCS need to be set at the configuration file as well:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db.host=192.168.10.172&lt;br /&gt;
db.port=3306&lt;br /&gt;
db.schema=dcsdb&lt;br /&gt;
db.username=db_user&lt;br /&gt;
db.password=db_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After setting these database related properties within the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file, the admin needs to call the &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh&amp;lt;/b&amp;gt; script as super user of the system. &lt;br /&gt;
&lt;br /&gt;
Database related settings made in the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file are read by this script first and taken as defaults. Nevertheless, each default value can be overwritten by the admin via the command line. Passwords need to be set by the admin via the command line in every case for security reasons.&lt;br /&gt;
&lt;br /&gt;
If all database properties have been set correctly within the &amp;lt;b&amp;gt;/etc/documents-collaboration/dcs.properties&amp;lt;/b&amp;gt; file, a valid call to the &amp;lt;b&amp;gt;/usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh&amp;lt;/b&amp;gt; script is e.g. the following one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo /usr/share/open-xchange-documents-collaboration/bin/initdcsdb.sh -a --dcsdb-pass=db_password --mysql-root-passwd=mysql_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The default logging path is set in &amp;lt;b&amp;gt;/etc/documents-collaboration/logback-spring.xml&amp;lt;/b&amp;gt; and points to &amp;lt;b&amp;gt;/var/log/open-xchange/documents-collaboration/documents-collaboration.log&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Documents Collaboration Service will be started by executing the following comand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo systemctl start open-xchange-documents-collaboration.service&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A command line tool allows to check the values in the database&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# /usr/share/open-xchange-documents-collaboration/bin/documents-collaboration-admin.sh -l&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| ID                  | Host          | Interface     | JMSPort |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| 192.168.10.25:61616 | 192.168.10.25 | 192.168.10.25 |   61616 |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
JMX access to the DCS can be enabled and configured in dcs.properties.&lt;br /&gt;
By default it is disabled. To enable JMX change the appropriate line to&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
jmx.enabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Middleware node===&lt;br /&gt;
&lt;br /&gt;
No additional package repositories and no additional packages are required to be installed for the Middleware in order to use  DCS.&lt;br /&gt;
&lt;br /&gt;
Discovery of running DCSs via the database is configured in file &amp;lt;b&amp;gt;/opt/open-xchange/etc/documents-collaboration-client.properties&amp;lt;/b&amp;gt;.&lt;br /&gt;
Add the appropriate values to access the ''dcsdb'' Database as previously set during the DCS configuration (see above):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
com.openexchange.dcs.client.database.connectionURL=jdbc:mysql://192.168.10.172:3306/dcsdb&lt;br /&gt;
com.openexchange.dcs.client.database.userName=db_user&lt;br /&gt;
com.openexchange.dcs.client.database.password=db_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A command line tool allows to check the values in the database&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ /opt/open-xchange/sbin/documents-collaboration-admin -l&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| ID                  | Host          | Interface     | JMSPort |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
| 192.168.10.25:61616 | 192.168.10.25 | 192.168.10.25 |   61616 |&lt;br /&gt;
+---------------------+---------------+---------------+---------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Apache configuration===&lt;br /&gt;
&lt;br /&gt;
For working websocket support Apache version 2.4.10 or newer is required.&lt;br /&gt;
&lt;br /&gt;
The Apache module proxy_wstunnel has to be enabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a2enmod proxy_wstunnel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the the following entries need to be added to the Apache configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;Proxy balancer://oxcluster_ws&amp;gt;&lt;br /&gt;
  Order Deny,Allow&lt;br /&gt;
  Allow from all&lt;br /&gt;
  BalancerMember ws://localhost:8009 timeout=1900 smax=0 ttl=60 retry=60 loadfactor=50 keepalive=On route=OX1&lt;br /&gt;
  ProxySet stickysession=JSESSIONID|jsessionid scolonpathdelim=On&lt;br /&gt;
  SetEnv proxy-initial-not-pooled&lt;br /&gt;
  SetEnv proxy-sendchunked&lt;br /&gt;
&amp;lt;/Proxy&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ProxyPass /appsuite/rt2 balancer://oxcluster_ws/rt2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A running Apache server on the system needs to be restarted or triggered to reload its configuration after the above changes have been made.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
&lt;br /&gt;
OX Documents offers runtime information via JMX about the document editors as well as the OX Documentconverter. This [[AppSuite:DocumentsMonitoring|article]] guides to the information how to access JMX data, configure and use Jolokia and integrate with munin.&lt;br /&gt;
&lt;br /&gt;
== Printing and legacy MS binary formats Editing ==&lt;br /&gt;
&lt;br /&gt;
For .DOC/.XLS/.PPT and/or printing support from OX Documents the Document Converter and readerengine components have to be installed separately (license key required)&lt;br /&gt;
&lt;br /&gt;
* See [[AppSuite:DocumentConverterInstall|Document converter / readerengine installation instructions]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
To enable the OX Documents Applications for OX Drive the associated permission has to be set.&lt;br /&gt;
&lt;br /&gt;
The default setting for all users is changed in the file '''documents.properties''' in the directory ''/opt/open-xchange/etc''.&lt;br /&gt;
&lt;br /&gt;
After installation the functionality is disabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Enables or disables the &amp;quot;text&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.text=true&lt;br /&gt;
&lt;br /&gt;
# Enables or disables the &amp;quot;spreadsheet&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.spreadsheet=true&lt;br /&gt;
&lt;br /&gt;
# Enables or disables the &amp;quot;presentation&amp;quot; module capability globally.&lt;br /&gt;
# com.openexchange.capability.presentation=true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following line enables the functionality:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Enables or disables the &amp;quot;text&amp;quot; module capability globally.&lt;br /&gt;
com.openexchange.capability.text=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starting with 7.6.2, you can disable the text portal app. In '''permissions.properties''':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
permissions=textportaldisabled&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collaboration on shared documents ===&lt;br /&gt;
&lt;br /&gt;
If OX Documents functionality is used for guest users in a cluster of application servers, this setting needs to be adjusted to false in order to also have guest sessions available in the distributed storage.&lt;br /&gt;
&lt;br /&gt;
in ''/opt/open-xchange/etc/sharing.properties'' &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Specifies whether guest sessions are treated as transient or not. Transient&lt;br /&gt;
# sessions are only held in the short-term session containers, and are not put&lt;br /&gt;
# into the distributed session storage. Defaults to &amp;quot;true&amp;quot;.&lt;br /&gt;
com.openexchange.share.transientSessions=false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
com.openechange.share.transientSessions has to be set to false.&lt;br /&gt;
&lt;br /&gt;
=== Spell Checking===&lt;br /&gt;
&lt;br /&gt;
OX Text and OX Presentation use ''hunspell'' for spell checking functionality.&lt;br /&gt;
By default Spellchecking is enabled in ''/opt/open-xchange/etc/settings/office.properties''&lt;br /&gt;
with the following entry&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Determines whether online spelling is enabled for office documents.&lt;br /&gt;
# Possible values: true|false&lt;br /&gt;
# If this property is missing true is taken.&lt;br /&gt;
io.ox/office//module/spellingEnabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installation of the ''hunspell'' package for your platform the shared library and the US English dictionaries are available. Please check the file location the pkg files were installed into. (For instance on CentOS, use rpm -q –filesbypkg hunspell and verify the path of the lib files to be configured below)&lt;br /&gt;
Also verify that the Hunspell dictonary is present and not renamed to &amp;quot;myspell&amp;quot; etc.. if the dictionary is renamed, you will have to use that in the config below. &lt;br /&gt;
&lt;br /&gt;
Additional dictionaries are published for your platform as packages hunspell-de-de,  hunspell-fr, ...&lt;br /&gt;
&lt;br /&gt;
Spell checking has to be configured in the file ''/opt/open-xchange/etc/hunspell.properties''.&lt;br /&gt;
The values for the shared library file and dictionary path have to be set according to the platform.&lt;br /&gt;
&lt;br /&gt;
This example shows the values for Debian:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# The name and location of the hunspell library&lt;br /&gt;
# Default value: &amp;quot;/usr/lib/x86_64-linux-gnu/libhunspell-1.3.so.0&amp;quot;&lt;br /&gt;
com.openexchange.spellchecker.hunspell.library=/usr/lib/x86_64-linux-gnu/libhunspell-1.4.so.0&lt;br /&gt;
# The location of the dictionaries&lt;br /&gt;
# Default value: &amp;quot;/usr/share/hunspell&amp;quot;&lt;br /&gt;
com.openexchange.spellchecker.hunspell.dictionaries=/usr/share/hunspell&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If spellchecking is enabled and the library path or dictionary path is wrong a warning is logged.&lt;br /&gt;
&lt;br /&gt;
If a language is not supported by a hunspell dictionary (or produces error messages in the console log) myspell dictionaries are a working alternative.&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
OX Documents support different levels to provide document templates for users.&lt;br /&gt;
&lt;br /&gt;
A number of ready-to-use templates for letters, memos, resumes, home budget, presentations, etc is included with the system. These templates are made available in a directory at each system node by installation of the package open-xchange-documents-templates. The path to this directory is defined in the office.properties file &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Defines the absolute path where document templates are located inside the local (!) file system.&lt;br /&gt;
# The templates are displayed in the documents applications.&lt;br /&gt;
# If this property is missing a default '/opt/open-xchange/templates/documents' is taken.&lt;br /&gt;
io.ox/office//module/templatePath = /opt/open-xchange/templates/documents&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The content in the directory specified by the path must comply to the following rules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/opt/open-xchange/templates/documents     &lt;br /&gt;
|     &lt;br /&gt;
----&amp;gt; text [application type]&lt;br /&gt;
|     |   &lt;br /&gt;
|     ----&amp;gt; en-US [language-region]&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; en [language fallback, en is also fallback for all other non-convered languages]&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; de-DE&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; de&lt;br /&gt;
|     |     &lt;br /&gt;
|     ----&amp;gt; common [language independent, used in addition to the language specific ones]&lt;br /&gt;
|         &lt;br /&gt;
----&amp;gt; spreadsheet&lt;br /&gt;
|         &lt;br /&gt;
----&amp;gt; presentation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A context administrator can additionally provide global templates for all users in the same context.&lt;br /&gt;
If logged in with this role folders can be added to or removed from the list of global template folders. For regular users the list is displayed without the permission to modify it.&lt;br /&gt;
&lt;br /&gt;
[[File:template-folder.png|border|600px|caption]]&lt;br /&gt;
&lt;br /&gt;
Users can create and manage their own templates. These user templates are stored and retrieved from the user’s root folder (“My files”). In addition to the root folder the user can define more template folders, sub-folders or even external folders in the “Documents” section of the “Settings” menu. This helps to organize templates and allows cleanup of the root folder by removal of templates.&lt;br /&gt;
&lt;br /&gt;
For installations of OX Spreadsheet based on Appsuite 7.8.0 and 7.8.1 please see [http://oxpedia.org/wiki/index.php?title=AppSuite:Spreadsheet_Installation_Guide_7_8_1 here] for different installation modes.&lt;br /&gt;
&lt;br /&gt;
=== OX Documents in Browser Tabs ===&lt;br /&gt;
&lt;br /&gt;
OX Documents based on Appsuite 7.10.2 opens new documents in new tabs in the browser by default.&lt;br /&gt;
&lt;br /&gt;
To disable this feature an stay in the single tab mode you have to set the attribute 'openInSingleTab' in as-config.yml&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Override certain settings&lt;br /&gt;
default:&lt;br /&gt;
    host: all&lt;br /&gt;
    openInSingleTab: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Mobile_API_Facade&amp;diff=25164</id>
		<title>AppSuite:Mobile API Facade</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Mobile_API_Facade&amp;diff=25164"/>
		<updated>2019-12-11T10:03:46Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Mobile API Facade =&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
&lt;br /&gt;
The Mobile API Facade is a server component that brings the new native mobile mail apps together with the OX App Suite. We’ve built the façade based on the technology used and proven in the OX App Suite middleware. The facade is developed in Java, utilizing the OSGI Framework.&lt;br /&gt;
&lt;br /&gt;
The Facade provides offline friendly HTTP interface by doing the work, the connections through the HTTP API, to the OX App Suite and providing only the data the offline capable clients need. In some cases multiple requests to the OX App Suite are combined into one for its clients.The facade also offers a method to tell the clients that information on the server haven’t changed since the last time the client asked for it. This reduces the amount of data to transmit to the clients under certain circumstances, especially important in mobile networks were bandwidth (and overall traffic) is limited. Thanks to facade some functionality can be shared among all clients and need only get implemented once. One example for this is the teaser text extraction, and HTML mail handling in general.The facade also provides a pluggable authentication system. In the default case, login request are just forwarded to the middleware. In more advanced use-cases, the login request is forwarded to IDM of the customer and an OX session is created from the access token from the IDM. For clients this is pretty straightforward.&lt;br /&gt;
&lt;br /&gt;
== License information ==&lt;br /&gt;
&lt;br /&gt;
=== Used 3rd party licenses ===&lt;br /&gt;
&lt;br /&gt;
In addition to the 3rd party software [https://www.open-xchange.com/legal/licenses-ox-app-suite/ used by AppSuite], the Mobile API Facade uses to following libraries:&lt;br /&gt;
&lt;br /&gt;
* [https://www.open-xchange.com/fileadmin/user_upload/images/portfolio/license/MIT_License_Generic.pdf Project Lombok (The MIT License]&lt;br /&gt;
* [https://www.open-xchange.com/fileadmin/user_upload/images/portfolio/license/MIT_License_Generic.pdf Semver4J (The MIT License)]&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
The Mobile API Facade has to be installed alongside an OX App Suite installation. It requires at least OX App Suite v7.8.4.&lt;br /&gt;
&lt;br /&gt;
== Version Matrix ==&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
|- &lt;br /&gt;
|colspan=1|'''OX App Suite Core Version'''&lt;br /&gt;
|colspan=1|'''Mobile API Facade Version'''&lt;br /&gt;
|colspan=1|'''Version-Stream'''&lt;br /&gt;
|-&lt;br /&gt;
|v7.8.4&lt;br /&gt;
|v1.0.x&lt;br /&gt;
|stable-1.0&lt;br /&gt;
|-&lt;br /&gt;
|v7.10.0&lt;br /&gt;
|v1.2.x&lt;br /&gt;
|stable-1.2&lt;br /&gt;
|-&lt;br /&gt;
|v7.10.1&lt;br /&gt;
|v1.4.x&lt;br /&gt;
|stable-1.4&lt;br /&gt;
|-&lt;br /&gt;
|v7.10.2&lt;br /&gt;
|v1.6.x&lt;br /&gt;
|stable-1.6&lt;br /&gt;
|-&lt;br /&gt;
|v7.10.3&lt;br /&gt;
|v1.8.x&lt;br /&gt;
|stable-1.8&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Mobile API Facade API ==&lt;br /&gt;
&lt;br /&gt;
Further information about the Mobile API Facade API can be found at:&lt;br /&gt;
https://documentation.open-xchange.com/components/facade/1.0.0/&lt;br /&gt;
&lt;br /&gt;
= OX Mail Server-side Installation and Configuration on OX App Suite v7.10.3 =&lt;br /&gt;
&lt;br /&gt;
This chapter describes how the backend components of OX Mail are installed and configured on the server.&lt;br /&gt;
&lt;br /&gt;
== Available packages ==&lt;br /&gt;
&lt;br /&gt;
Mobile API Facade is available with the following backend packages:&lt;br /&gt;
&lt;br /&gt;
* ''open-xchange-mobile-api-facade''&lt;br /&gt;
&lt;br /&gt;
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=rhelname|pc2v=RHEL6|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-mobile-api-facade&lt;br /&gt;
 &lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=rhelname|pc2v=RHEL7|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 9.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=debianname|pc2v=DebianStretch|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 10.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=debianname|pc2v=DebianBuster|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 === &lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=susename|pc2v=SLE_12|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OX Mail Server-side Installation and Configuration on OX App Suite 7.8.x and 7.10.x =&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of OX Mobile API Facade to the latest maintenance release, add the following entry to &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/open-xchange.list&amp;lt;/tt&amp;gt;. Replace VERSION with the link for the stream of versions as listed above in the version matrix (e.g. stable-1.2) or a specific version you are using (e.g. 1.2.3).&lt;br /&gt;
&lt;br /&gt;
This chapter describes how the backend components of OX Mail are installed and configured on the server.&lt;br /&gt;
&lt;br /&gt;
== Available packages ==&lt;br /&gt;
&lt;br /&gt;
Mobile API Facade is available with the following backend packages:&lt;br /&gt;
&lt;br /&gt;
* ''open-xchange-mobile-api-facade''&lt;br /&gt;
&lt;br /&gt;
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=rhelname|pc2v=RHEL6|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-mobile-api-facade&lt;br /&gt;
 &lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=rhelname|pc2v=RHEL7|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 8.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=debianname|pc2v=DebianJessie|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 9.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=debianname|pc2v=DebianStretch|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 10.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=debianname|pc2v=DebianBuster|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 === &lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=susename|pc2v=SLE_12|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
= Configuration Mobile API Facade =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
To be able to use the native mail apps the Mobile API Facade needs to be installed in front of the OX App Suite middleware. This document describes how to configure the Mobile API Facade.&lt;br /&gt;
&lt;br /&gt;
The Mobile API Facade stores its configuration in the files &amp;lt;code&amp;gt;/opt/open-xchange/mobile-api-facade/etc/facade.properties&amp;lt;/code&amp;gt; (the global configuration) and in &amp;lt;code&amp;gt;/opt/open-xchange/mobile-api-facade/etc/mobile-api-facade-config.yml&amp;lt;/code&amp;gt; (hostname specific configuration). Both files support the same configuration properties as can be seen on https://documentation.open-xchange.com/components/mobile-api-facade/config/1.8/.&lt;br /&gt;
&lt;br /&gt;
== Connection to the OX App Suite Middleware ==&lt;br /&gt;
&lt;br /&gt;
After installation of the facade package (&amp;quot;open-xchange-mobile-api-facade&amp;quot;) the property &amp;lt;code&amp;gt;com.openexchange.mobile.api.facade.MiddlewareBaseUrl&amp;lt;/code&amp;gt; needs to get set to the correct URL. This property needs to be explicitly configured by the administrator. It has no default value. Its possible to connect the Mobile API Facade directly to a middleware process, but this is highly discouraged. The Mobile API Facade should always connect to a middleware process through a load balancer.&lt;br /&gt;
&lt;br /&gt;
An example:&lt;br /&gt;
&lt;br /&gt;
 com.openexchange.mobile.api.facade.MiddlewareBaseUrl=https://appsuite.example.com/appsuite/api&lt;br /&gt;
&lt;br /&gt;
After this configuration the open-xchange-mobile-api-facade needs to get restarted.&lt;br /&gt;
&lt;br /&gt;
== Proxy configuration ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Proxy balancer://oxcluster_facade&amp;gt;&lt;br /&gt;
         Order Allow,Deny&lt;br /&gt;
         Allow from all&lt;br /&gt;
         BalancerMember http://appsuite-middleware1.example.com:8007 timeout=100 smax=0 ttl=60 retry=60 loadfactor=50 keepalive=On route=FOX1&lt;br /&gt;
         BalancerMember http://appsuite-middleware2.example.com:8007 timeout=100 smax=0 ttl=60 retry=60 loadfactor=50 keepalive=On route=FOX2&lt;br /&gt;
 &lt;br /&gt;
         ProxySet stickysession=JSESSIONID|jsessionidscolonpathdelim=On&lt;br /&gt;
         SetEnv proxy-initial-not-pooled&lt;br /&gt;
         SetEnv proxy-sendchunked&lt;br /&gt;
 &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ProxyPass /services/api-facade balancer://oxcluster_facade/services/api-facade&lt;br /&gt;
&lt;br /&gt;
== Traffic compression ==&lt;br /&gt;
&lt;br /&gt;
The clients need to exchange a lot of data with the facade to accomplish the task of a mail client. This traffic can be compressed. Clients add the header &amp;quot;Accept-Encoding: gzip,deflate&amp;quot; by default. For this to work the Apache web server in front of the facade needs to handle this as the facade itself is not returning compressed response bodies.&lt;br /&gt;
&lt;br /&gt;
For Apache HTTPD &amp;lt;code&amp;gt;{mod_deflate}&amp;lt;/code&amp;gt; needs to be enabled and the following line needs to be added to your virtual host:&lt;br /&gt;
&lt;br /&gt;
 AddOutputFilterByType DEFLATE text/html text/plain text/javascript application/javascript text/css &lt;br /&gt;
 text/xml application/xml text/x-js application/x-javascript application/json&lt;br /&gt;
&lt;br /&gt;
== Starting/Stopping the Facade Service ==&lt;br /&gt;
&lt;br /&gt;
The facade runs as its own service independent of the normal OX App Suite middleware. For this on Debian-based system it can be started with&lt;br /&gt;
&lt;br /&gt;
 service open-xchange-mobile-api-facade start&lt;br /&gt;
&lt;br /&gt;
It can be stopped with&lt;br /&gt;
&lt;br /&gt;
 service open-xchange-mobile-api-facade stop&lt;br /&gt;
&lt;br /&gt;
== Rereading configuration from disk ==&lt;br /&gt;
&lt;br /&gt;
All configuration properties which are marked as reloadable can be configured without restarting the Mobile API Facade by using the &amp;lt;code&amp;gt;reloadconfiguration&amp;lt;/code&amp;gt; utility. As the Mobile API Facade runs in its own process you need to tell &amp;lt;code&amp;gt;reloadconfiguration&amp;lt;/code&amp;gt; to connect it instead of the Middleware. This can be done by:&lt;br /&gt;
&lt;br /&gt;
 reloadconfiguration -p 1100&lt;br /&gt;
&lt;br /&gt;
== Ports ==&lt;br /&gt;
&lt;br /&gt;
As the Mobile API Facade is its own process it also has its own JMX port and its own RMI port. The default JMX port is 9995 and the default RMI port is 1100. These ports needs to be explicitly specified to the command line tools using either JMX or RMI.&lt;br /&gt;
&lt;br /&gt;
== Configuration of Mobile API Facade behavior ==&lt;br /&gt;
&lt;br /&gt;
This can be configured in facade.properties and mobile-api-facade-config.yml.&lt;br /&gt;
&lt;br /&gt;
=== Multiple host names ===&lt;br /&gt;
&lt;br /&gt;
The Mobile API Facade supports multiple host names on one instance, that are configured differently. These can be configured in mobile-api-facade-config.yml. This file in YAML format. Beware that indentation is really important in YAML.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[ host name ]:&lt;br /&gt;
	[ properties, you want to configure ]&lt;br /&gt;
&lt;br /&gt;
[ host name ]:&lt;br /&gt;
	[ properties, you want to configure ]&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The allowed properties are the same as allowed in facade.properties. You can find a complete list at https://documentation.open-xchange.com/components/mobile-api-facade/config/1.8/.&lt;br /&gt;
&lt;br /&gt;
=== Custom properties ===&lt;br /&gt;
&lt;br /&gt;
It's possible to configure custom properties to be returned to clients. This is usefull to return special configurations to your clients. Custom properties are key/attribute values under the &amp;quot;customProperties&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
appsuite.example.com:&lt;br /&gt;
    customProperties:&lt;br /&gt;
        custom.specific.property: true&lt;br /&gt;
        custom.specific.property.2: &amp;quot;value&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Client specific configuration ===&lt;br /&gt;
&lt;br /&gt;
By implementing the  client specific feature the above configuration possibilities got extended. We now have to use YAML lists for each host name. This allows to add multiple different configurations to one host configuration. You can add a list of matchers in the &amp;quot;matches&amp;quot; key to a host configuration. The first &amp;quot;matches&amp;quot; entry for a given host name that matches to the given User-Agent header sent by the client will be used. Further evaluation is not done at runtime. Configuration properties need to be on the same indentation level as the &amp;quot;matches&amp;quot; key. These host configurations inherit a default configuration from the configuration in facade.properties. Otherwise they need to be complete. They don't inherit configuration properties from other places.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[ host name ]:&lt;br /&gt;
	- matches:&lt;br /&gt;
		  [ matchers, you want to match against ]&lt;br /&gt;
		  [ properties, you want to configure ]&lt;br /&gt;
	- matches:&lt;br /&gt;
		  [ matchers, you want to match against ]&lt;br /&gt;
		  [ properties, you want to configure ]&lt;br /&gt;
	...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
The iOS version supported in the beginning was iOS 9 and up. At some point in time due to technical reasons support for iOS 9 and 10 was dropped and the application supported iOS 11 and up. When you now want to update all installations on iOS 11 and up to the latest app version but leave old installations in intact you can use the force upgrade feature of the apps. Keep in mind that the matching process stops when the first match is found. If no match was found the default configuration is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
appsuite.example.com:&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '11.0-'&lt;br /&gt;
          brand: 'OpenXchange'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.minimumClientVersion.ios: '11.2'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: false&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '-10.99'&lt;br /&gt;
		  brand: 'OpenXchange'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Matchers ===&lt;br /&gt;
&lt;br /&gt;
Several matchers are possible. All match against values in the User-Agent header.&lt;br /&gt;
&lt;br /&gt;
- platform: This matcher allows it to match only for &amp;quot;Android&amp;quot; or &amp;quot;iOS&amp;quot;&lt;br /&gt;
- version: This matcher checks against the application version. This is not the marketing version displayed in the About screen of the application.&lt;br /&gt;
- osVersion: The version of the operating system on the client device&lt;br /&gt;
- device: This matches against the exact device model.&lt;br /&gt;
    brand: This matches against the brand name of the app. By default this is &amp;quot;OpenXchange&amp;quot;. Versions specifically branded for customers have a unique brand name.&lt;br /&gt;
&lt;br /&gt;
=== Version matching ===&lt;br /&gt;
&lt;br /&gt;
For the matchers 'version' and 'osVersion' we allow to match concrete versions or version ranges. When adding a matcher with a concrete version, just put the version number as string attribute after the matcher name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
appsuite.example.com:&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '11.0'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When matching a range we are always matching inclusive. You can either use a closed range, a range with a given start value and an end value, or an open range with either a start value or an end value. Keep in mind that to match all versions lower then '11.0' you need use a probably non-existing version number like '10.99'.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
appsuite.example.com:&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '11.0-'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: true&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '-10.99'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
In order to check whether installation went successful you may want to run&lt;br /&gt;
&lt;br /&gt;
   $ curl -v http://localhost:8007/services/api-facade/v1/version&lt;br /&gt;
&lt;br /&gt;
That should return a JSON string like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{&amp;quot;version&amp;quot;:&amp;quot;1.6.8&amp;quot;,&amp;quot;commitHash&amp;quot;:&amp;quot;9e90d6072407b73c3e05b86ce724962af1a3de61&amp;quot;,&amp;quot;middlewareVersion&amp;quot;:&amp;quot;7.10.2-Rev15&amp;quot;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Mobile_API_Facade&amp;diff=25163</id>
		<title>AppSuite:Mobile API Facade</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Mobile_API_Facade&amp;diff=25163"/>
		<updated>2019-12-11T09:08:44Z</updated>

		<summary type="html">&lt;p&gt;Choeger: fixed Balancer Member lines&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Mobile API Facade =&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
&lt;br /&gt;
The Mobile API Facade is a server component that brings the new native mobile mail apps together with the OX App Suite. We’ve built the façade based on the technology used and proven in the OX App Suite middleware. The facade is developed in Java, utilizing the OSGI Framework.&lt;br /&gt;
&lt;br /&gt;
The Facade provides offline friendly HTTP interface by doing the work, the connections through the HTTP API, to the OX App Suite and providing only the data the offline capable clients need. In some cases multiple requests to the OX App Suite are combined into one for its clients.The facade also offers a method to tell the clients that information on the server haven’t changed since the last time the client asked for it. This reduces the amount of data to transmit to the clients under certain circumstances, especially important in mobile networks were bandwidth (and overall traffic) is limited. Thanks to facade some functionality can be shared among all clients and need only get implemented once. One example for this is the teaser text extraction, and HTML mail handling in general.The facade also provides a pluggable authentication system. In the default case, login request are just forwarded to the middleware. In more advanced use-cases, the login request is forwarded to IDM of the customer and an OX session is created from the access token from the IDM. For clients this is pretty straightforward.&lt;br /&gt;
&lt;br /&gt;
== License information ==&lt;br /&gt;
&lt;br /&gt;
=== Used 3rd party licenses ===&lt;br /&gt;
&lt;br /&gt;
In addition to the 3rd party software [https://www.open-xchange.com/legal/licenses-ox-app-suite/ used by AppSuite], the Mobile API Facade uses to following libraries:&lt;br /&gt;
&lt;br /&gt;
* [https://www.open-xchange.com/fileadmin/user_upload/images/portfolio/license/MIT_License_Generic.pdf Project Lombok (The MIT License]&lt;br /&gt;
* [https://www.open-xchange.com/fileadmin/user_upload/images/portfolio/license/MIT_License_Generic.pdf Semver4J (The MIT License)]&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
The Mobile API Facade has to be installed alongside an OX App Suite installation. It requires at least OX App Suite v7.8.4.&lt;br /&gt;
&lt;br /&gt;
== Version Matrix ==&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
|- &lt;br /&gt;
|colspan=1|'''OX App Suite Core Version'''&lt;br /&gt;
|colspan=1|'''Mobile API Facade Version'''&lt;br /&gt;
|colspan=1|'''Version-Stream'''&lt;br /&gt;
|-&lt;br /&gt;
|v7.8.4&lt;br /&gt;
|v1.0.x&lt;br /&gt;
|stable-1.0&lt;br /&gt;
|-&lt;br /&gt;
|v7.10.0&lt;br /&gt;
|v1.2.x&lt;br /&gt;
|stable-1.2&lt;br /&gt;
|-&lt;br /&gt;
|v7.10.1&lt;br /&gt;
|v1.4.x&lt;br /&gt;
|stable-1.4&lt;br /&gt;
|-&lt;br /&gt;
|v7.10.2&lt;br /&gt;
|v1.6.x&lt;br /&gt;
|stable-1.6&lt;br /&gt;
|-&lt;br /&gt;
|v7.10.3&lt;br /&gt;
|v1.8.x&lt;br /&gt;
|stable-1.8&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Mobile API Facade API ==&lt;br /&gt;
&lt;br /&gt;
Further information about the Mobile API Facade API can be found at:&lt;br /&gt;
https://documentation.open-xchange.com/components/facade/1.0.0/&lt;br /&gt;
&lt;br /&gt;
= OX Mail Server-side Installation and Configuration on OX App Suite v7.10.3 =&lt;br /&gt;
&lt;br /&gt;
This chapter describes how the backend components of OX Mail are installed and configured on the server.&lt;br /&gt;
&lt;br /&gt;
== Available packages ==&lt;br /&gt;
&lt;br /&gt;
Mobile API Facade is available with the following backend packages:&lt;br /&gt;
&lt;br /&gt;
* ''open-xchange-mobile-api-facade''&lt;br /&gt;
&lt;br /&gt;
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=rhelname|pc2v=RHEL6|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-mobile-api-facade&lt;br /&gt;
 &lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=rhelname|pc2v=RHEL7|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 9.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=debianname|pc2v=DebianStretch|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 10.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=debianname|pc2v=DebianBuster|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 === &lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/stable-1.8|pc2n=susename|pc2v=SLE_12|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= OX Mail Server-side Installation and Configuration on OX App Suite 7.8.x and 7.10.x =&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of OX Mobile API Facade to the latest maintenance release, add the following entry to &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/open-xchange.list&amp;lt;/tt&amp;gt;. Replace VERSION with the link for the stream of versions as listed above in the version matrix (e.g. stable-1.2) or a specific version you are using (e.g. 1.2.3).&lt;br /&gt;
&lt;br /&gt;
This chapter describes how the backend components of OX Mail are installed and configured on the server.&lt;br /&gt;
&lt;br /&gt;
== Available packages ==&lt;br /&gt;
&lt;br /&gt;
Mobile API Facade is available with the following backend packages:&lt;br /&gt;
&lt;br /&gt;
* ''open-xchange-mobile-api-facade''&lt;br /&gt;
&lt;br /&gt;
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.&lt;br /&gt;
&lt;br /&gt;
=== Redhat Enterprise Linux 6 or CentOS 6 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=rhelname|pc2v=RHEL6|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-mobile-api-facade&lt;br /&gt;
 &lt;br /&gt;
=== Redhat Enterprise Linux 7 or CentOS 7 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange yum configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=rhelname|pc2v=RHEL7|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ yum install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 8.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=debianname|pc2v=DebianJessie|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 9.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=debianname|pc2v=DebianStretch|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== Debian GNU/Linux 10.0 ===&lt;br /&gt;
&lt;br /&gt;
Add the following repositories to your Open-Xchange apt configuration:&lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=debianname|pc2v=DebianBuster|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
=== SUSE Linux Enterprise Server 12 === &lt;br /&gt;
&lt;br /&gt;
 {{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mobile-api-facade/VERSION|pc2n=susename|pc2v=SLE_12|mobile-api-facade}}&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
 $ zypper install open-xchange-mobile-api-facade&lt;br /&gt;
&lt;br /&gt;
= Configuration Mobile API Facade =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
To be able to use the native mail apps the Mobile API Facade needs to be installed in front of the OX App Suite middleware. This document describes how to configure the Mobile API Facade.&lt;br /&gt;
&lt;br /&gt;
The Mobile API Facade stores its configuration in the files &amp;lt;code&amp;gt;/opt/open-xchange/mobile-api-facade/etc/facade.properties&amp;lt;/code&amp;gt; (the global configuration) and in &amp;lt;code&amp;gt;/opt/open-xchange/mobile-api-facade/etc/mobile-api-facade-config.yml&amp;lt;/code&amp;gt; (hostname specific configuration). Both files support the same configuration properties as can be seen on https://documentation.open-xchange.com/components/mobile-api-facade/config/1.8/.&lt;br /&gt;
&lt;br /&gt;
== Connection to the OX App Suite Middleware ==&lt;br /&gt;
&lt;br /&gt;
After installation of the facade package (&amp;quot;open-xchange-mobile-api-facade&amp;quot;) the property &amp;lt;code&amp;gt;com.openexchange.mobile.api.facade.MiddlewareBaseUrl&amp;lt;/code&amp;gt; needs to get set to the correct URL. This property needs to be explicitly configured by the administrator. It has no default value. Its possible to connect the Mobile API Facade directly to a middleware process, but this is highly discouraged. The Mobile API Facade should always connect to a middleware process through a load balancer.&lt;br /&gt;
&lt;br /&gt;
An example:&lt;br /&gt;
&lt;br /&gt;
 com.openexchange.mobile.api.facade.MiddlewareBaseUrl=https://appsuite.example.com/appsuite/api&lt;br /&gt;
&lt;br /&gt;
After this configuration the open-xchange-mobile-api-facade needs to get restarted.&lt;br /&gt;
&lt;br /&gt;
== Proxy configuration ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Proxy balancer://oxcluster_facade&amp;gt;&lt;br /&gt;
         Order Allow,Deny&lt;br /&gt;
         Allow from all&lt;br /&gt;
         BalancerMember http://appsuite-middleware1.example.com:8007 timeout=100 smax=0 ttl=60 retry=60 loadfactor=50 keepalive=On route=FOX1&lt;br /&gt;
         BalancerMember http://appsuite-middleware2.example.com:8007 timeout=100 smax=0 ttl=60 retry=60 loadfactor=50 keepalive=On route=FOX2&lt;br /&gt;
 &lt;br /&gt;
         ProxySet stickysession=JSESSIONID|jsessionidscolonpathdelim=On&lt;br /&gt;
         SetEnv proxy-initial-not-pooled&lt;br /&gt;
         SetEnv proxy-sendchunked&lt;br /&gt;
 &amp;lt;/Proxy&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ProxyPass /services/api-facade balancer://oxcluster_facade/services/api-facade&lt;br /&gt;
&lt;br /&gt;
== Traffic compression ==&lt;br /&gt;
&lt;br /&gt;
The clients need to exchange a lot of data with the facade to accomplish the task of a mail client. This traffic can be compressed. Clients add the header &amp;quot;Accept-Encoding: gzip,deflate&amp;quot; by default. For this to work the Apache web server in front of the facade needs to handle this as the facade itself is not returning compressed response bodies.&lt;br /&gt;
&lt;br /&gt;
For Apache HTTPD &amp;lt;code&amp;gt;{mod_deflate}&amp;lt;/code&amp;gt; needs to be enabled and the following line needs to be added to your virtual host:&lt;br /&gt;
&lt;br /&gt;
 AddOutputFilterByType DEFLATE text/html text/plain text/javascript application/javascript text/css &lt;br /&gt;
 text/xml application/xml text/x-js application/x-javascript application/json&lt;br /&gt;
&lt;br /&gt;
== Starting/Stopping the Facade Service ==&lt;br /&gt;
&lt;br /&gt;
The facade runs as its own service independent of the normal OX App Suite middleware. For this on Debian-based system it can be started with&lt;br /&gt;
&lt;br /&gt;
 service open-xchange-mobile-api-facade start&lt;br /&gt;
&lt;br /&gt;
It can be stopped with&lt;br /&gt;
&lt;br /&gt;
 service open-xchange-mobile-api-facade stop&lt;br /&gt;
&lt;br /&gt;
== Rereading configuration from disk ==&lt;br /&gt;
&lt;br /&gt;
All configuration properties which are marked as reloadable can be configured without restarting the Mobile API Facade by using the &amp;lt;code&amp;gt;reloadconfiguration&amp;lt;/code&amp;gt; utility. As the Mobile API Facade runs in its own process you need to tell &amp;lt;code&amp;gt;reloadconfiguration&amp;lt;/code&amp;gt; to connect it instead of the Middleware. This can be done by:&lt;br /&gt;
&lt;br /&gt;
 reloadconfiguration -p 1100&lt;br /&gt;
&lt;br /&gt;
== Ports ==&lt;br /&gt;
&lt;br /&gt;
As the Mobile API Facade is its own process it also has its own JMX port and its own RMI port. The default JMX port is 9995 and the default RMI port is 1100. These ports needs to be explicitly specified to the command line tools using either JMX or RMI.&lt;br /&gt;
&lt;br /&gt;
== Configuration of Mobile API Facade behavior ==&lt;br /&gt;
&lt;br /&gt;
This can be configured in facade.properties and mobile-api-facade-config.yml.&lt;br /&gt;
&lt;br /&gt;
=== Multiple host names ===&lt;br /&gt;
&lt;br /&gt;
The Mobile API Facade supports multiple host names on one instance, that are configured differently. These can be configured in mobile-api-facade-config.yml. This file in YAML format. Beware that indentation is really important in YAML.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[ host name ]:&lt;br /&gt;
	[ properties, you want to configure ]&lt;br /&gt;
&lt;br /&gt;
[ host name ]:&lt;br /&gt;
	[ properties, you want to configure ]&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The allowed properties are the same as allowed in facade.properties. You can find a complete list at https://documentation.open-xchange.com/components/mobile-api-facade/config/1.8/.&lt;br /&gt;
&lt;br /&gt;
=== Custom properties ===&lt;br /&gt;
&lt;br /&gt;
It's possible to configure custom properties to be returned to clients. This is usefull to return special configurations to your clients. Custom properties are key/attribute values under the &amp;quot;customProperties&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
appsuite.example.com:&lt;br /&gt;
    customProperties:&lt;br /&gt;
        custom.specific.property: true&lt;br /&gt;
        custom.specific.property.2: &amp;quot;value&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Client specific configuration ===&lt;br /&gt;
&lt;br /&gt;
By implementing the  client specific feature the above configuration possibilities got extended. We now have to use YAML lists for each host name. This allows to add multiple different configurations to one host configuration. You can add a list of matchers in the &amp;quot;matches&amp;quot; key to a host configuration. The first &amp;quot;matches&amp;quot; entry for a given host name that matches to the given User-Agent header sent by the client will be used. Further evaluation is not done at runtime. Configuration properties need to be on the same indentation level as the &amp;quot;matches&amp;quot; key. These host configurations inherit a default configuration from the configuration in facade.properties. Otherwise they need to be complete. They don't inherit configuration properties from other places.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[ host name ]:&lt;br /&gt;
	- matches:&lt;br /&gt;
		  [ matchers, you want to match against ]&lt;br /&gt;
		  [ properties, you want to configure ]&lt;br /&gt;
	- matches:&lt;br /&gt;
		  [ matchers, you want to match against ]&lt;br /&gt;
		  [ properties, you want to configure ]&lt;br /&gt;
	...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
The iOS version supported in the beginning was iOS 9 and up. At some point in time due to technical reasons support for iOS 9 and 10 was dropped and the application supported iOS 11 and up. When you now want to update all installations on iOS 11 and up to the latest app version but leave old installations in intact you can use the force upgrade feature of the apps. Keep in mind that the matching process stops when the first match is found. If no match was found the default configuration is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
appsuite.example.com:&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '11.0-'&lt;br /&gt;
          brand: 'OpenXchange'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.minimumClientVersion.ios: '11.2'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: false&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '-10.99'&lt;br /&gt;
		  brand: 'OpenXchange'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Matchers ===&lt;br /&gt;
&lt;br /&gt;
Several matchers are possible. All match against values in the User-Agent header.&lt;br /&gt;
&lt;br /&gt;
- platform: This matcher allows it to match only for &amp;quot;Android&amp;quot; or &amp;quot;iOS&amp;quot;&lt;br /&gt;
- version: This matcher checks against the application version. This is not the marketing version displayed in the About screen of the application.&lt;br /&gt;
- osVersion: The version of the operating system on the client device&lt;br /&gt;
- device: This matches against the exact device model.&lt;br /&gt;
    brand: This matches against the brand name of the app. By default this is &amp;quot;OpenXchange&amp;quot;. Versions specifically branded for customers have a unique brand name.&lt;br /&gt;
&lt;br /&gt;
=== Version matching ===&lt;br /&gt;
&lt;br /&gt;
For the matchers 'version' and 'osVersion' we allow to match concrete versions or version ranges. When adding a matcher with a concrete version, just put the version number as string attribute after the matcher name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
appsuite.example.com:&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '11.0'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When matching a range we are always matching inclusive. You can either use a closed range, a range with a given start value and an end value, or an open range with either a start value or an end value. Keep in mind that to match all versions lower then '11.0' you need use a probably non-existing version number like '10.99'.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
appsuite.example.com:&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '11.0-'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: true&lt;br /&gt;
	- matches:&lt;br /&gt;
		  platform: 'iOS'&lt;br /&gt;
		  osVersion: '-10.99'&lt;br /&gt;
	  com.openexchange.mobile.api.facade.returnNonPrimaryAccounts: false&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24931</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24931"/>
		<updated>2019-10-17T11:34:53Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* SSL-related hints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [https://www.open-xchange.com/portfolio/ox-dovecot-pro/ OX Dovecot Pro] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// insert in your imports section:&lt;br /&gt;
// import javax.xml.ws.BindingProvider;&lt;br /&gt;
((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
    ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
        .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
        .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24930</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24930"/>
		<updated>2019-10-17T11:29:00Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [https://www.open-xchange.com/portfolio/ox-dovecot-pro/ OX Dovecot Pro] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        OXResellerContextServicePortType contextport = &lt;br /&gt;
contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // insert in your imports section:&lt;br /&gt;
        // import javax.xml.ws.BindingProvider;&lt;br /&gt;
        ((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
            ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
                .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
                .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24929</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24929"/>
		<updated>2019-10-17T11:26:23Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* OXaaS specific methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [http://dovecot.org Dovecot] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
==== SOAP API ====&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
==== REST API ====&lt;br /&gt;
&lt;br /&gt;
There's a growing number of REST APIs to access OXaaS, see https://documentation.open-xchange.com/, section ''Cloud Plugins API''.&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        OXResellerContextServicePortType contextport = &lt;br /&gt;
contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // insert in your imports section:&lt;br /&gt;
        // import javax.xml.ws.BindingProvider;&lt;br /&gt;
        ((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
            ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
                .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
                .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24928</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24928"/>
		<updated>2019-10-17T11:21:58Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Shared domains vs ordinary domains */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [http://dovecot.org Dovecot] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains, explicit domains and ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
==== Ordinary domains ====&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
==== Shared domains ====&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between all contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
or using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Shared-Domains REST API] (needs recent version).&lt;br /&gt;
&lt;br /&gt;
==== Explicit domains ====&lt;br /&gt;
&lt;br /&gt;
Recent versions support another type of domain called explicit domains. These domains must be explicitly added to contexts using the [https://documentation.open-xchange.com/components/cloudplugins/1.9.1/#tag/Explicit-Domains REST API] (needs recent version). You can add the same explicit domain to one or multiple contexts. If a context already contains an ordinary domain of the same name, it will be transformed into an explicit domain.&lt;br /&gt;
&lt;br /&gt;
Note that the explicit domain feature is not available by default, it must be activated for each customer, individually.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        OXResellerContextServicePortType contextport = &lt;br /&gt;
contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // insert in your imports section:&lt;br /&gt;
        // import javax.xml.ws.BindingProvider;&lt;br /&gt;
        ((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
            ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
                .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
                .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:SAML_SSO_Integration&amp;diff=24772</id>
		<title>AppSuite:SAML SSO Integration</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:SAML_SSO_Integration&amp;diff=24772"/>
		<updated>2019-07-22T09:37:34Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SAML SSO Integration =&lt;br /&gt;
&lt;br /&gt;
The content on this page has moved to https://documentation.open-xchange.com/latest/middleware/login_and_sessions/saml_2.0_sso.html.&lt;br /&gt;
&lt;br /&gt;
Note: Open-Xchange is in the process of migrating all its technical documentation to a new and improved documentation system (documentation.open-xchange.com). Please note as the migration takes place more information will be available on the new system and less on this system. Thank you for your understanding during this period of transition.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24762</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24762"/>
		<updated>2019-07-11T07:38:21Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* OXaaS specific methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [http://dovecot.org Dovecot] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains vs ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between multiple contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the combined values of drive and mail quota in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        OXResellerContextServicePortType contextport = &lt;br /&gt;
contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // insert in your imports section:&lt;br /&gt;
        // import javax.xml.ws.BindingProvider;&lt;br /&gt;
        ((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
            ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
                .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
                .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24761</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24761"/>
		<updated>2019-07-11T05:52:42Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* OXaaS specific methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [http://dovecot.org Dovecot] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains vs ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between multiple contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the same as the drive quota usage and max values in case the system has [https://documentation.open-xchange.com/latest/middleware/miscellaneous/quota.html#unified-quota unified quota] enabled.'''&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        OXResellerContextServicePortType contextport = &lt;br /&gt;
contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // insert in your imports section:&lt;br /&gt;
        // import javax.xml.ws.BindingProvider;&lt;br /&gt;
        ((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
            ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
                .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
                .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24760</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24760"/>
		<updated>2019-07-10T13:40:59Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* OXaaS specific methods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [http://dovecot.org Dovecot] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains vs ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between multiple contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
'''Note that the mail quota usage and max values are the same as the drive quota usage and max values in case the system has unified quota enabled.'''&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        OXResellerContextServicePortType contextport = &lt;br /&gt;
contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // insert in your imports section:&lt;br /&gt;
        // import javax.xml.ws.BindingProvider;&lt;br /&gt;
        ((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
            ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
                .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
                .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24715</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24715"/>
		<updated>2019-06-11T09:43:46Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Context creation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [http://dovecot.org Dovecot] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains vs ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between multiple contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        OXResellerContextServicePortType contextport = &lt;br /&gt;
contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // insert in your imports section:&lt;br /&gt;
        // import javax.xml.ws.BindingProvider;&lt;br /&gt;
        ((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
            ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
                .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
                .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry topbarHover = new Entry();&lt;br /&gt;
        topbarHover.setKey(&amp;quot;io.ox/dynamic-theme//topbarHover&amp;quot;);&lt;br /&gt;
        topbarHover.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry mainColor = new Entry();&lt;br /&gt;
        mainColor.setKey(&amp;quot;io.ox/dynamic-theme//mainColor&amp;quot;);&lt;br /&gt;
        mainColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry linkColor = new Entry();&lt;br /&gt;
        linkColor.setKey(&amp;quot;io.ox/dynamic-theme//linkColor&amp;quot;);&lt;br /&gt;
        linkColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry dynThemeCapa = new Entry();&lt;br /&gt;
        dynThemeCapa.setKey(&amp;quot;com.openexchange.capability.dynamic-theme&amp;quot;);&lt;br /&gt;
        dynThemeCapa.setValue(&amp;quot;true&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(topbarHover);&lt;br /&gt;
        configEntries.getEntries().add(mainColor);&lt;br /&gt;
        configEntries.getEntries().add(linkColor);&lt;br /&gt;
        configEntries.getEntries().add(dynThemeCapa);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24714</id>
		<title>OX as a Service Provisioning using SOAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=OX_as_a_Service_Provisioning_using_SOAP&amp;diff=24714"/>
		<updated>2019-06-11T09:40:42Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Create a context */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tutorial: Provision OX as a Service using SOAP =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[[OX_as_a_Service_Guide|OX as a Service]] is using the same code everybody can download and install using our&lt;br /&gt;
various guides. Since it is a hosted service using a reseller model, the provisioning api is using the [[Reseller_Bundle|Reseller Bundle]]&lt;br /&gt;
to extend the usual two administrative layers by an additional one.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange does also not contain a mail server in general, but requires one in order to act like a mail client. OX as a Service&lt;br /&gt;
is using [http://dovecot.org Dovecot] as mail server and thus extends the usual Open-Xchange provisioning capabilities by mechanisms&lt;br /&gt;
to manage some email specific settings.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of Contexts ==&lt;br /&gt;
&lt;br /&gt;
In order to provision users and groups into Open-Xchange, it is important to understand, that Open-Xchange is designed&lt;br /&gt;
for shared hosting environments in a way that it has to serve multiple tenants, customers, domains, or however you want to&lt;br /&gt;
name it. In Open-Xchange, we call that a '''Context'''. A context is a sealed container for users and groups. Users in a&lt;br /&gt;
context can not see users of other contexts, nor can they share data with users of other contexts (with the exception of&lt;br /&gt;
Open-Xchange publish and subscribe functionality).&lt;br /&gt;
&lt;br /&gt;
A usual scenario is to have a company, a family or in general one end customer in a context. One can also say, a context&lt;br /&gt;
is a domain, and usually that makes sense, since a company has one domain. However, Open-Xchange contexts are not limited&lt;br /&gt;
to one domain only.&lt;br /&gt;
&lt;br /&gt;
== Open-Xchange concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
A plain Open-Xchange installation consists of two administrative levels.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
=== oxadminmaster / root ===&lt;br /&gt;
&lt;br /&gt;
The root, or oxadminmaster account is used to&lt;br /&gt;
&lt;br /&gt;
* add, remove and configure filestores attached to Open-Xchange&lt;br /&gt;
* add, remove and configure databases attached to Open-Xchange&lt;br /&gt;
* add, remove and configure contexts&lt;br /&gt;
&lt;br /&gt;
and change parameters like add/remove domains, change per context filesystem quota, etc.&lt;br /&gt;
&lt;br /&gt;
Depending on the OX configuration, it is not able to add or remove users and groups, nor any other data within a context!&lt;br /&gt;
&lt;br /&gt;
=== Context admin ===&lt;br /&gt;
&lt;br /&gt;
The context admin is like an ordinary Open-Xchange user, except that it can add, remove and edit&lt;br /&gt;
users and groups within Open-Xchange using the provisioning API.&lt;br /&gt;
In addition, it inherits shared data of users, that are deleted.&lt;br /&gt;
'''In OX as a Service, however, the context admin cannot read, send or receive mail.'''&lt;br /&gt;
&lt;br /&gt;
== OX as a Service concept of provisioning ==&lt;br /&gt;
&lt;br /&gt;
As written before, plain Open-Xchange only has one root account. In a reseller scenario, that would&lt;br /&gt;
mean if we want resellers to be able to create contexts for their customers, we would have to hand out our&lt;br /&gt;
root account. Since that is not desirable, we added another layer via the [[Reseller_Bundle|Reseller Bundle]] as&lt;br /&gt;
mentioned earlier.&lt;br /&gt;
&lt;br /&gt;
# root level, usually we call that oxadminmaster&lt;br /&gt;
# subadmin level / brand level&lt;br /&gt;
# context level&lt;br /&gt;
&lt;br /&gt;
root and context level don't change, except that context level can be [[Reseller_Bundle#Restrictions|restricted]].&lt;br /&gt;
&lt;br /&gt;
The subadmin account can only add, remove or configure contexts. Depending on the configuration of the&lt;br /&gt;
OX as a Service tenant, it can or can NOT add, remove and configure users within contexts.&lt;br /&gt;
Contexts created by a subadmin account can not be seen by other subadmin accounts.&lt;br /&gt;
&lt;br /&gt;
=== What is a brand? ===&lt;br /&gt;
&lt;br /&gt;
A brand is a customers subadmin login to the OXaaS SOAP provisioning API.&lt;br /&gt;
&lt;br /&gt;
== OX as a Service specifics ==&lt;br /&gt;
&lt;br /&gt;
=== Shared domains vs ordinary domains ===&lt;br /&gt;
&lt;br /&gt;
In order to create a user in Open-Xchange, you have to set an email address for that user.&lt;br /&gt;
This will directly lead into a domain to be created into OXaaS bound to that user and its context,&lt;br /&gt;
if that domain does not already exists and is owned by a different context.&lt;br /&gt;
&lt;br /&gt;
If you want to share domains between multiple contexts, you have to use shared domains.&lt;br /&gt;
Shared domains must be created in advance using the &amp;lt;tt&amp;gt;createSharedDomain&amp;lt;/tt&amp;gt; method (see [[#OXaaS_specific_methods|OXaaS specific methods]])&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;existsMailAlias&amp;lt;/tt&amp;gt; method to check for the existence of an alias before you create it.&lt;br /&gt;
&lt;br /&gt;
=== Catchall accounts ===&lt;br /&gt;
&lt;br /&gt;
If the feature is enabled in your contract, you can create catchall mail aliases bound to users&lt;br /&gt;
within contexts.&lt;br /&gt;
&lt;br /&gt;
=== User permissions ===&lt;br /&gt;
&lt;br /&gt;
See [[OX_as_a_Service_Provisioning_using_SOAP#Set_OXaaS_permissions|OXaaS permission]] description below.&lt;br /&gt;
&lt;br /&gt;
=== User name/login uniqueness ===&lt;br /&gt;
&lt;br /&gt;
Due to the architecture of OXaaS, a login/username must be unique across all created contexts. That means it is not&lt;br /&gt;
possible to create two &amp;quot;oxadmin&amp;quot; accounts. This limitation applies per brand.&lt;br /&gt;
&lt;br /&gt;
=== Display name uniqueness ===&lt;br /&gt;
&lt;br /&gt;
In contrary to the login/name of users, display names must only be unique within each context.&lt;br /&gt;
That is because it is used e.g. in the shared folder list of e.g. calendar, drive, contacts in OX.&lt;br /&gt;
Also it is used as folder name when mounting OX via WEBDAV.&lt;br /&gt;
&lt;br /&gt;
It is no problem, however, to have one &amp;quot;Steve Smith&amp;quot; in one context, and another &amp;quot;Steve Smith” in another context.&lt;br /&gt;
&lt;br /&gt;
=== No email for &amp;quot;oxadmin&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
The architecture of OX as a Service does not allow the context admin to have email.&lt;br /&gt;
&lt;br /&gt;
== Provisioning ==&lt;br /&gt;
&lt;br /&gt;
=== OXaaS specific methods ===&lt;br /&gt;
&lt;br /&gt;
The following SOAP methods are specific to OXaaS and are NOT part of the general Open-Xchange provisioning API.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS specific SOAP calls and its authentication requirements&lt;br /&gt;
! Method&lt;br /&gt;
! Functionality&lt;br /&gt;
! Authentication&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsage&lt;br /&gt;
| get the overall mail quota usage of all users within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createSharedDomain&lt;br /&gt;
| create a shared domain&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsLogin&lt;br /&gt;
| check whether user login already exists. Note: a users login must be unique within all users for your subadmin account and NOT only per context!&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! existsMailAlias&lt;br /&gt;
| check whether given mail alias already exists&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! createDomainCatchall&lt;br /&gt;
| create a domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getQuotaUsagePerUser&lt;br /&gt;
| get mail quota usage of the individual user within the given context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! listDomainCatchalls&lt;br /&gt;
| list all existing domain catchalls&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setMailQuota&lt;br /&gt;
| set the mail quota of the individual user within the context&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteDomainCatchall&lt;br /&gt;
| delete the given domain catchall&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getPermissions&lt;br /&gt;
| list given users permissions&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! enablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! disablePermissions&lt;br /&gt;
| enable provided permissions for given user&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setExpiryDate&lt;br /&gt;
| store expiry date for the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiryDate&lt;br /&gt;
| get expiry date stored for user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! deleteExpiryDate&lt;br /&gt;
| delete the expiry date stored in the given user&lt;br /&gt;
| Context Admin&lt;br /&gt;
|-&lt;br /&gt;
! getExpiredUsers &lt;br /&gt;
| retrieve list of expired users&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! getMailQuota&lt;br /&gt;
| get the mail quota of the individual user within the context&lt;br /&gt;
| Subadmin&lt;br /&gt;
|-&lt;br /&gt;
! setPasswordHash&lt;br /&gt;
| directly store provided pwHash into userPassword attribute of matching ldap entry. Note: Input will be validated against valid mechanisms.&lt;br /&gt;
| Context Admin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The WSDL source file for these methods contain documentation for each of the calls and parameters.&lt;br /&gt;
You can download it here: http://software.open-xchange.com/products/appsuite/doc/oxasservice/OXaaSService.wsdl&lt;br /&gt;
&lt;br /&gt;
=== OX Core Provisioning API ===&lt;br /&gt;
&lt;br /&gt;
The core provisioning API consists of four namespaces:&lt;br /&gt;
&lt;br /&gt;
# Context management&lt;br /&gt;
# User management&lt;br /&gt;
# Group management&lt;br /&gt;
# Resource management&lt;br /&gt;
&lt;br /&gt;
Some of these namespaces share the same data structures such as &amp;lt;tt&amp;gt;Credentials&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Context&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;User&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:provisioning-core.png|1000 px]]&lt;br /&gt;
&lt;br /&gt;
=== Reference implementation ===&lt;br /&gt;
&lt;br /&gt;
The reference implementation of the European OX as a Service system can be found in the {{APSPackage|name=OX as a Service}} APS package&lt;br /&gt;
for [http://www.odin.com/products/automation/ Odin Service Automation].&lt;br /&gt;
&lt;br /&gt;
=== Workflow ===&lt;br /&gt;
&lt;br /&gt;
==== Subadmin credentials ====&lt;br /&gt;
&lt;br /&gt;
The first requirement is to get subadmin credentials for your company. Please follow the steps&lt;br /&gt;
[[OX_as_a_Service_Guide#How_to_become_a_customer.3F|documented here]] to get such an account.&lt;br /&gt;
&lt;br /&gt;
Together with the login and password you will also retrieve the provisioning URL to be used by&lt;br /&gt;
all SOAP requests. In addition, it is required that you give us a list of ip addresses or network(s)&lt;br /&gt;
that should be allowed to access the provisioning system.&lt;br /&gt;
&lt;br /&gt;
==== WSDL files ====&lt;br /&gt;
&lt;br /&gt;
Just point your browser to the provisioning URL you got from us. You will find some services listed there.&lt;br /&gt;
You will need the following services from that list:&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXaaSService?wsdl: OX as a Service specific functions&lt;br /&gt;
; https://hostname/webservices/OXResellerContextService?wsdl: Context management&lt;br /&gt;
; https://hostname/webservices/OXResellerUserService?wsdl: User management&lt;br /&gt;
&lt;br /&gt;
and optionally&lt;br /&gt;
&lt;br /&gt;
; https://hostname/webservices/OXResellerGroupService?wsdl: Group management&lt;br /&gt;
; https://hostname/webservices/OXResellerResourceService?wsdl: Resource management&lt;br /&gt;
&lt;br /&gt;
==== SOAP API documentation ====&lt;br /&gt;
&lt;br /&gt;
The general SOAP API documentation can be found at this URL:&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html&lt;br /&gt;
&lt;br /&gt;
That document contains links to the Javadoc documentation for the RMI api, but&lt;br /&gt;
that is more or less the same as the SOAP API.&lt;br /&gt;
&lt;br /&gt;
In addition, there's the general, non OXaaS specific [[Open-Xchange_Provisioning_using_SOAP|wiki page]].&lt;br /&gt;
&lt;br /&gt;
==== Create a context ====&lt;br /&gt;
&lt;br /&gt;
Once you have the credentials in place, you are ready to create your first context.&lt;br /&gt;
&lt;br /&gt;
Creating a context requires to create the first user in that context, that is the context admin, see above.&lt;br /&gt;
&lt;br /&gt;
Mandatory settings for a context are&lt;br /&gt;
&lt;br /&gt;
; name: name of the context&lt;br /&gt;
; quota: file quota in MB for that context ('''Note:''' that is file, not mail!)&lt;br /&gt;
; taxonomy: must be set to the login of your subadmin account, see below&lt;br /&gt;
&lt;br /&gt;
'''Important:''' In OXaaS, the name of the context must always start with your subadmin login with an underscore appended. E.g. when&lt;br /&gt;
your subadmin login is &amp;lt;tt&amp;gt;johndoe&amp;lt;/tt&amp;gt;, the all your context names must start with &amp;lt;tt&amp;gt;johndoe_&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
Optional settings&lt;br /&gt;
&lt;br /&gt;
; mainColor: io.ox/dynamic-theme//mainColor&lt;br /&gt;
; linkColor: io.ox/dynamic-theme//linkColor&lt;br /&gt;
; for further theme parameters, check https://documentation.open-xchange.com/latest/ui/theming/dynamic-theming.html&lt;br /&gt;
&lt;br /&gt;
; id: A numerical id bound to the context. When you create a context, this id will be generated. You will need that later when you manage users. The id can be looked up via the context name.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
The settings brandtaxonomy and the other optional settings except id are part of the userAttributes SOAP field.&lt;br /&gt;
All other settings can easily be set via simple SOAP settings. userAttributes is a hash that contains some settings&lt;br /&gt;
that are not available in all setups of Open-Xchange. It allows to extend Open-Xchange functionality dynamically like&lt;br /&gt;
done in OXaaS.&lt;br /&gt;
&lt;br /&gt;
The hash looks like this:&lt;br /&gt;
&lt;br /&gt;
 userAttributes =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 somevalue can be an array again, e.g.:&lt;br /&gt;
 &lt;br /&gt;
 somevalue =&amp;gt; entries =&amp;gt; EntryArray&lt;br /&gt;
 &lt;br /&gt;
 with EntryArray :=&lt;br /&gt;
 &lt;br /&gt;
 [&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;somekey&amp;quot;&lt;br /&gt;
     value =&amp;gt; somevalue },&lt;br /&gt;
   { key   =&amp;gt; &amp;quot;someotherkey&amp;quot;&lt;br /&gt;
     value =&amp;gt; someothervalue },&lt;br /&gt;
   ...&lt;br /&gt;
 ]&lt;br /&gt;
 &lt;br /&gt;
 and so on&lt;br /&gt;
&lt;br /&gt;
Example dump using perls &amp;lt;code&amp;gt;Data::Dumper&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
          'userAttributes' =&amp;gt; {&lt;br /&gt;
                              'entries' =&amp;gt; [&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; [&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#0000ff',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//topbarHover'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#ff0000',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//linkColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; '#00ff00',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'io.ox/dynamic-theme//mainColor'&lt;br /&gt;
                                                                     },&lt;br /&gt;
                                                                     {&lt;br /&gt;
                                                                       'value' =&amp;gt; 'true',&lt;br /&gt;
                                                                       'key' =&amp;gt; 'com.openexchange.capability.dynamic-theme'&lt;br /&gt;
                                                                     }                                                                   ]&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'config'&lt;br /&gt;
                                           },&lt;br /&gt;
                                           {&lt;br /&gt;
                                             'value' =&amp;gt; {&lt;br /&gt;
                                                        'entries' =&amp;gt; {&lt;br /&gt;
                                                                     'value' =&amp;gt; 'johndoe',&lt;br /&gt;
                                                                     'key' =&amp;gt; 'types'&lt;br /&gt;
                                                                   }&lt;br /&gt;
                                                      },&lt;br /&gt;
                                             'key' =&amp;gt; 'taxonomy'&lt;br /&gt;
                                           }&lt;br /&gt;
                                         ]&lt;br /&gt;
                            },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Admin User =====&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
&lt;br /&gt;
====== Timezones ======&lt;br /&gt;
&lt;br /&gt;
To get a list of all available timezones, you can run this short Java program:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.TimeZone;&lt;br /&gt;
&lt;br /&gt;
public class AllTimeZones {&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        for(final String zone : TimeZone.getAvailableIDs() ) {&lt;br /&gt;
            System.out.println(zone);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Languages ======&lt;br /&gt;
&lt;br /&gt;
This is the list of currently supported languages in OXaaS:&lt;br /&gt;
&lt;br /&gt;
 ja_JP&lt;br /&gt;
 de_DE&lt;br /&gt;
 es_ES&lt;br /&gt;
 es_MX&lt;br /&gt;
 fr_FR&lt;br /&gt;
 it_IT&lt;br /&gt;
 nl_NL&lt;br /&gt;
 pl_PL&lt;br /&gt;
 zh_TW&lt;br /&gt;
 en_US&lt;br /&gt;
 en_GB&lt;br /&gt;
&lt;br /&gt;
==== Create users ====&lt;br /&gt;
&lt;br /&gt;
Creating users requires the following parameters&lt;br /&gt;
&lt;br /&gt;
; name: login name of the context admin&lt;br /&gt;
; password: password&lt;br /&gt;
; email: email address of the context admin&lt;br /&gt;
; displayname: displayname (usually surname givenname)&lt;br /&gt;
; surname: surname&lt;br /&gt;
; givenname: given name&lt;br /&gt;
; lang: language, e.g. en_GB, en_US, de_DE, ...&lt;br /&gt;
; timezone: Java timezone such as Europe/Berlin,&lt;br /&gt;
; moduleaccess: the module access combination name&lt;br /&gt;
; mailquota: the mail quota of the user in MB&lt;br /&gt;
&lt;br /&gt;
Timezones and languages like documented earlier.&lt;br /&gt;
&lt;br /&gt;
Valid values for moduleaccess are:&lt;br /&gt;
&lt;br /&gt;
* webmail_plus&lt;br /&gt;
* groupware_standard&lt;br /&gt;
* groupware_advanced&lt;br /&gt;
* groupware_premium&lt;br /&gt;
&lt;br /&gt;
Other settings are not supported.&lt;br /&gt;
&lt;br /&gt;
===== userAttributes =====&lt;br /&gt;
&lt;br /&gt;
It might be required you have to set some specific attributes per user like the Edition Type as&lt;br /&gt;
done by the OXaaS APS package.&lt;br /&gt;
&lt;br /&gt;
There's a choice of 7 different edition types:&lt;br /&gt;
&lt;br /&gt;
; webmail: bound to webmail_plus&lt;br /&gt;
; basic: bound to groupware_standard&lt;br /&gt;
; advanced: bound to groupware_advanced&lt;br /&gt;
; pro: bound to groupware_premium&lt;br /&gt;
; pro_m: bound to groupware_premium&lt;br /&gt;
; pro_l: bound to groupware_premium&lt;br /&gt;
; pro_xl: bound to groupware_premium&lt;br /&gt;
&lt;br /&gt;
which can be set within each users oxaas_edition_type within a tree oxaas:&lt;br /&gt;
&lt;br /&gt;
 'userAttributes' =&amp;gt; {&lt;br /&gt;
                     'entries' =&amp;gt; {&lt;br /&gt;
                                  'key' =&amp;gt; 'oxaas',&lt;br /&gt;
                                  'value' =&amp;gt; {&lt;br /&gt;
                                             'entries' =&amp;gt; {&lt;br /&gt;
                                                          'key' =&amp;gt; 'oxaas_edition_type',&lt;br /&gt;
                                                          'value' =&amp;gt; 'pro_l'&lt;br /&gt;
                                                          }&lt;br /&gt;
                                             }&lt;br /&gt;
                                 }&lt;br /&gt;
                     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
see [[#Standalone_example:_createOXaaSUser|createuser example script]]&lt;br /&gt;
&lt;br /&gt;
===== Create the user in Open-Xchange =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt; to create users.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Although there are three create methods in the SOAP user service API, you have to use the method &amp;lt;code&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
and specify one of the names listed above.&lt;br /&gt;
&lt;br /&gt;
===== Set mail quota =====&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;OXaaSService-&amp;gt;setMailQuota&amp;lt;/code&amp;gt; call to set the mail quota for the user created above.&lt;br /&gt;
&lt;br /&gt;
===== Set OXaaS permissions =====&lt;br /&gt;
&lt;br /&gt;
====== Explanation ======&lt;br /&gt;
&lt;br /&gt;
The OXaaS permissions allow to enable or disable a certain set of features.&lt;br /&gt;
Currently, the following permissions are available:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ OXaaS permissions&lt;br /&gt;
! Permission&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
! SEND&lt;br /&gt;
| User is allowed to send mail&lt;br /&gt;
|-&lt;br /&gt;
! RECEIVE&lt;br /&gt;
| User is allowed to receive mail&lt;br /&gt;
|-&lt;br /&gt;
! MAILLOGIN&lt;br /&gt;
| User can login using IMAP from external; webmail is not affected&lt;br /&gt;
|-&lt;br /&gt;
! WEBLOGIN&lt;br /&gt;
| User can login to OX webmail.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The permission names are case insensitive.&lt;br /&gt;
The WEBLOGIN permission is the same as the [http://software.open-xchange.com/products/appsuite/doc/RMI/admin-core/com/openexchange/admin/rmi/dataobjects/User.html#setMailenabled%28java.lang.Boolean%29 &amp;lt;tt&amp;gt;Mailenabled&amp;lt;/tt&amp;gt;] permission in the user data of the Open-Xchange core api. The permission&lt;br /&gt;
OXaaS api provides another way to enable/disable it.&lt;br /&gt;
&lt;br /&gt;
* Use the name and password of the context admin user of the context you created earlier and define&lt;br /&gt;
a Credentials object.&lt;br /&gt;
* Find the numerical id of the context e.g. in using &amp;lt;code&amp;gt;OXResellerContextService-&amp;gt;getData(name=&amp;quot;contextname&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Find the numerical id of the user either by using &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;getData(name=&amp;quot;username&amp;quot;)&amp;lt;/code&amp;gt; or use/store the return value of &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use one of &amp;lt;code&amp;gt;OXaaSService-&amp;gt;enablePermissions&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;OXaaSService-&amp;gt;disablePermissions&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXaaSService-&amp;gt;getPermissions&amp;lt;/code&amp;gt;&lt;br /&gt;
to change or retrieve permissions. Permissions must always be provided as an array of 1 or more permissions.&lt;br /&gt;
&lt;br /&gt;
=== SOAP provisioning feature matrix ===&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;br /&gt;
&lt;br /&gt;
The table below shows what method(s) to use and what to set in order to configure the different feature sets.&lt;br /&gt;
&lt;br /&gt;
The value in the row ''Module Access Name'' must be given as a parameter to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt;&lt;br /&gt;
or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The values in the row ''Capabilities'' must be given as parameters to the &amp;lt;code&amp;gt;userAttributes&amp;lt;/code&amp;gt; member of the &amp;lt;code&amp;gt;User&amp;lt;/code&amp;gt; object that&lt;br /&gt;
should be changed and then passed to &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;change&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;createByModuleAccessName&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note: &amp;lt;code&amp;gt;OXResellerUserService-&amp;gt;changeByModuleAccessName&amp;lt;/code&amp;gt; does NOT change these capabilities!'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Provisioning Feature Matrix&lt;br /&gt;
! Feature&lt;br /&gt;
! Module Access Name&lt;br /&gt;
! Capabilities ''(mandatory values in bold, others are optional)''&lt;br /&gt;
|-&lt;br /&gt;
! Web Mail&lt;br /&gt;
| webmail_plus&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''false'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''false'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Basic&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_standard&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Advanced&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_advanced&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Pro&lt;br /&gt;
| &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;com.openexchange.capability.drive = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.text = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = '''true'''&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = '''true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== List of available capabilities (incomplete) ===&lt;br /&gt;
&lt;br /&gt;
These features are controlled by the [[ConfigCascade]].&lt;br /&gt;
&lt;br /&gt;
For drive and documents the following settings are responsible:&lt;br /&gt;
&lt;br /&gt;
; OX Drive :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.drive = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Docs :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.document_preview = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.spreadsheet = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.text = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.presentation = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.remote_presenter = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-docs = true/false&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; OX Guard :&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-mail = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;com.openexchange.capability.guard-drive = true/false&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using [[OX_as_a_Service_Provisioning_using_SOAP#Standalone_example:_createOXaaSContext|this perl example]]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g. this&lt;br /&gt;
&lt;br /&gt;
       logouturl =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;io.ox/core//customLocations/logout&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;logouturl&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
is setting the ConfigCascade setting &amp;lt;tt&amp;gt;io.ox/core//customLocations/logout&amp;lt;/tt&amp;gt; to the string “logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  io.ox/core//customLocations/logout = &amp;quot;logouturl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding&lt;br /&gt;
&lt;br /&gt;
       oxdrive =&amp;gt; {&lt;br /&gt;
               setting =&amp;gt; &amp;quot;com.openexchange.capability.drive&amp;quot;,&lt;br /&gt;
               value   =&amp;gt; &amp;quot;true&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
in that example would turn on drive.&lt;br /&gt;
&lt;br /&gt;
== Code Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
==== Generating the SOAP client ====&lt;br /&gt;
&lt;br /&gt;
Since Open-Xchange is using [http://cxf.apache.org/ Apache CXF] for SOAP, we recommend to use the &amp;lt;tt&amp;gt;wsdl2java&amp;lt;/tt&amp;gt;&lt;br /&gt;
code generator from that package.&lt;br /&gt;
&lt;br /&gt;
The Open-Xchange SOAP services are divided into multiple parts, which makes the code generation a little&lt;br /&gt;
complex.&lt;br /&gt;
&lt;br /&gt;
In OXaaS we need at least three services in order to create contexts and users:&lt;br /&gt;
&lt;br /&gt;
* OXResellerContextService&lt;br /&gt;
* OXResellerUserService&lt;br /&gt;
* OXaaSService&lt;br /&gt;
&lt;br /&gt;
The shell script below generates the stubs of these three services into the directory defined in the &amp;lt;tt&amp;gt;CODEBASE&amp;lt;/tt&amp;gt;&lt;br /&gt;
variable. In addition, you have to set &amp;lt;tt&amp;gt;WSDLURL&amp;lt;/tt&amp;gt; to point it to the provisioning URL you will get from us as&lt;br /&gt;
mentioned [[#Subadmin_credentials|earlier]].&lt;br /&gt;
&lt;br /&gt;
Note: when running against a DEV container without valid SSL certs (e.g. self-signed SSL certs), it is required to add the servers cert into your java keystore first:&lt;br /&gt;
&lt;br /&gt;
# Get the cert e.g. by &amp;lt;code&amp;gt;openssl s_client -connect my.oxaas.webservices.host.net:443&amp;lt;/code&amp;gt; (the part between BEGIN CERTIFICATE and END CERTIFICATE) or by exporting from a web browser. Put it in a file named for example &amp;lt;code&amp;gt;my.oxaas.webservices.host.net.crt&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Import it in a custom TrustStore. Assign a password; in this example we assume &amp;quot;secret&amp;quot;: &amp;lt;code&amp;gt;keytool -import -trustcacerts -alias my.oxaas.webservices.host.net -keystore my.oxaas.webservices.host.net.jks -file my.oxaas.webservices.host.net.crt -storetype JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
# Supply it to the JVM by patching the CXF wsdl2java script (e.g. &amp;lt;code&amp;gt;/opt/apache-cxf-3.1.14/bin/wsdl2java&amp;lt;/code&amp;gt;) and add the following arguments: &amp;lt;code&amp;gt;-Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy&amp;amp;paste the shell script below into a file and run it using the &amp;lt;tt&amp;gt;bash&amp;lt;/tt&amp;gt; shell. &amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; the script assumes the CODEBASE target lives in its own dedicated ecplise project, and executes a &amp;lt;code&amp;gt;rm -rf $CODEBASE&amp;lt;/code&amp;gt; for a clean start. For other usecases (shared eclipse project, etc), please adjust to your needs / be careful!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 1. download apache-cxf tarball, extract it and &amp;quot;cd&amp;quot; into the directory, e.g.&lt;br /&gt;
#    tar zxvpf apache-cxf-3.1.10.tar.gz; cd apache-cxf-3.1.10&lt;br /&gt;
#    NOTE: cxf versions 3.0 do NOT work ootb with java-1.8!&lt;br /&gt;
# 2. change variables CODEBASE, JAVA_HOME and WSDLURL&lt;br /&gt;
# 3. run this script &amp;quot;bash oxaas-wsdl2java&amp;quot;&lt;br /&gt;
export JAVA_HOME=&amp;quot;/usr/lib/jvm/java-1.8.0-openjdk-amd64/&amp;quot;&lt;br /&gt;
CODEBASE=&amp;quot;/home/oxgit/workspace/OXaaSJClient/src&amp;quot;&lt;br /&gt;
WSDLURL=&amp;quot;https://youroxaashost/webservices&amp;quot;&lt;br /&gt;
&lt;br /&gt;
rm -rf $CODEBASE&lt;br /&gt;
frontend=jaxws21&lt;br /&gt;
dbinding=jaxb&lt;br /&gt;
&lt;br /&gt;
JAXBTMP=/tmp/jaxb$$.xml&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
cat&amp;lt;&amp;lt;EOF &amp;gt; $JAXBTMP&lt;br /&gt;
&amp;lt;jaxb:bindings version=&amp;quot;2.1&amp;quot;&lt;br /&gt;
xmlns:jaxb=&amp;quot;http://java.sun.com/xml/ns/jaxb&amp;quot;&lt;br /&gt;
xmlns:xjc=&amp;quot;http://java.sun.com/xml/ns/jaxb/xjc&amp;quot;&lt;br /&gt;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;jaxb:globalBindings generateElementProperty=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/jaxb:bindings&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.context&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerContextService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.user&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.reseller.admin.openexchange.com=${pname}&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.reseller.admin.openexchange.com/xsd=${pname}.reseller.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.reseller.admin.openexchange.com/xsd=${pname}.reseller.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.soap.admin.openexchange.com/xsd=${pname}.soap.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://dataobjects.rmi.admin.openexchange.com/xsd=${pname}.rmi.dataobjects&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://exceptions.rmi.admin.openexchange.com/xsd=${pname}.rmi.exceptions&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://rmi.java/xsd=${pname}.java.rmi&amp;quot; \&lt;br /&gt;
-p &amp;quot;http://io.java/xsd=${pname}.java.io&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXResellerUserService?wsdl&lt;br /&gt;
&lt;br /&gt;
pname=&amp;quot;com.openexchange.oxaas.extra&amp;quot;&lt;br /&gt;
bin/wsdl2java -databinding $dbinding -frontend $frontend -client -impl -d $CODEBASE -keep -b $JAXBTMP \&lt;br /&gt;
-p &amp;quot;http://soap.oxaas.admin.openexchange.com/=${pname}&amp;quot; \&lt;br /&gt;
${WSDLURL}/OXaaSService?wsdl&lt;br /&gt;
&lt;br /&gt;
rm -f $JAXBTMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you generate the code into an existing eclipse project, you should have three main packages as shown in&lt;br /&gt;
the image below&lt;br /&gt;
&lt;br /&gt;
[[File:OXaaSSOAPClientEclipse.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example Client ====&lt;br /&gt;
&lt;br /&gt;
In the following example, the context creation and the user creation is separated into different&lt;br /&gt;
programs.&lt;br /&gt;
&lt;br /&gt;
To summarize some essential requirements from the example below:&lt;br /&gt;
&lt;br /&gt;
* The name of each context you create must start with your subadmin name followed by an underscore &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;&lt;br /&gt;
* You must set the userAttribute &amp;lt;tt&amp;gt;taxonomy&amp;lt;/tt&amp;gt; at least&lt;br /&gt;
* The context admin user must get the &amp;lt;tt&amp;gt;groupware_premium&amp;lt;/tt&amp;gt; access permission&lt;br /&gt;
&lt;br /&gt;
===== Build / run instructions =====&lt;br /&gt;
&lt;br /&gt;
====== Eclipse ======&lt;br /&gt;
&lt;br /&gt;
We assume, you have created the Java client stub(s) as documented above and have it as a separate eclipse project. The individual clients given below are assumed to live in a different ecplise project which references the Java client stubs in their classpath.&lt;br /&gt;
&lt;br /&gt;
====== Command Line ======&lt;br /&gt;
&lt;br /&gt;
For maximum simplicity let's assume you use the source files given below without the &amp;lt;code&amp;gt;package&amp;lt;/code&amp;gt; statement. Put them in an &amp;lt;code&amp;gt;examples/&amp;lt;/code&amp;gt; subdirectory.&lt;br /&gt;
&lt;br /&gt;
Let's assume furthermore you created the Java client stubs in a different directory, e.g. &amp;lt;code&amp;gt;codebase/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change into that directory to compile all the Java stub files&lt;br /&gt;
&lt;br /&gt;
 cd codebase/&lt;br /&gt;
 find . -name \*.java  | xargs javac&lt;br /&gt;
&lt;br /&gt;
Back in the working directory where the source files given below are created, you can compile / run them like&lt;br /&gt;
&lt;br /&gt;
 cd ../examples/&lt;br /&gt;
 javac -cp ../codebase MyContextClientExample.java&lt;br /&gt;
 java -cp .:../codebase MyContextClientExample&lt;br /&gt;
&lt;br /&gt;
====== SSL-related hints ======&lt;br /&gt;
&lt;br /&gt;
When working against a dev machine with self-signed certs, the same certificate trust related options are required as explained above for the &amp;lt;code&amp;gt;wsdl2java&amp;lt;/code&amp;gt; script (with the same TrustStore and password):&lt;br /&gt;
&lt;br /&gt;
 -Djavax.net.ssl.trustStore=my.oxaas.webservices.host.net.jks -Djavax.net.ssl.trustStorePassword=secret -Djavax.net.ssl.trustStoreType=JKS&lt;br /&gt;
&lt;br /&gt;
It might be additionally helpful to enable SSL debug output: &amp;lt;code&amp;gt;-Djavax.net.debug=ssl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of now (2017-11) there is a flaw in the generated WSDL that it references HTTP SOAP addresses even when using HTTPS. This results in client programs trying to access the API via plain HTTP even after a successful SSL handshake and fetching the WSDL via HTTPS. This is bad as SOAP frames travel the network with credentials included in plain text.&lt;br /&gt;
&lt;br /&gt;
A possible workaround for the time being is to forcefully rewrite the protocol part of the different port urls into https with something like:&lt;br /&gt;
&lt;br /&gt;
After initializing the contextport using ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        OXResellerContextServicePortType contextport = &lt;br /&gt;
contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... add the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // insert in your imports section:&lt;br /&gt;
        // import javax.xml.ws.BindingProvider;&lt;br /&gt;
        ((BindingProvider)contextport).getRequestContext().put(&lt;br /&gt;
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,&lt;br /&gt;
            ((String)((BindingProvider)contextport).getRequestContext()&lt;br /&gt;
                .get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY))&lt;br /&gt;
                .replaceAll(&amp;quot;^http:&amp;quot;, &amp;quot;https:&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar adjustments are required for &amp;lt;code&amp;gt;userport&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;oxaasport&amp;lt;/code&amp;gt;, where they occur.&lt;br /&gt;
&lt;br /&gt;
===== Context creation =====&lt;br /&gt;
&lt;br /&gt;
The example below shows how to create a context in OXaaS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.ContextExistsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.Delete;&lt;br /&gt;
import com.openexchange.oxaas.context.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.context.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.context.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.Entry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPMapEntry;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.SOAPStringMapMap;&lt;br /&gt;
import com.openexchange.oxaas.context.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerContextService&lt;br /&gt;
 * &lt;br /&gt;
 * Create a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyContextClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User oxadmin = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();  &lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(subadminname);&lt;br /&gt;
        creds.setPassword(subadminpw);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry taxonomy = new SOAPMapEntry();&lt;br /&gt;
        taxonomy.setKey(&amp;quot;taxonomy&amp;quot;);&lt;br /&gt;
        SOAPStringMap taxtypeval = new SOAPStringMap();&lt;br /&gt;
        Entry taxtypeent = new Entry();&lt;br /&gt;
        taxtypeent.setKey(&amp;quot;types&amp;quot;);&lt;br /&gt;
        taxtypeent.setValue(subadminname);&lt;br /&gt;
        taxtypeval.getEntries().add(taxtypeent);&lt;br /&gt;
        taxonomy.setValue(taxtypeval);&lt;br /&gt;
&lt;br /&gt;
        SOAPMapEntry config = new SOAPMapEntry();&lt;br /&gt;
        config.setKey(&amp;quot;config&amp;quot;);&lt;br /&gt;
        SOAPStringMap configEntries = new SOAPStringMap();&lt;br /&gt;
&lt;br /&gt;
        Entry selectionColor = new Entry();&lt;br /&gt;
        selectionColor.setKey(&amp;quot;io.ox/dynamic-theme//selectionColor&amp;quot;);&lt;br /&gt;
        selectionColor.setValue(&amp;quot;#0000ff&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry frameColor = new Entry();&lt;br /&gt;
        frameColor.setKey(&amp;quot;io.ox/dynamic-theme//frameColor&amp;quot;);&lt;br /&gt;
        frameColor.setValue(&amp;quot;#ff0000&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        Entry iconColor = new Entry();&lt;br /&gt;
        iconColor.setKey(&amp;quot;io.ox/dynamic-theme//iconColor&amp;quot;);&lt;br /&gt;
        iconColor.setValue(&amp;quot;#00ff00&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        configEntries.getEntries().add(selectionColor);&lt;br /&gt;
        configEntries.getEntries().add(frameColor);&lt;br /&gt;
        configEntries.getEntries().add(iconColor);&lt;br /&gt;
        config.setValue(configEntries);&lt;br /&gt;
&lt;br /&gt;
        SOAPStringMapMap userattrs = new SOAPStringMapMap();&lt;br /&gt;
        userattrs.getEntries().add(taxonomy);&lt;br /&gt;
        userattrs.getEntries().add(config);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        ctx.setName(ctxname);&lt;br /&gt;
        ctx.setMaxQuota(10000l);&lt;br /&gt;
        ctx.setUserAttributes(userattrs);&lt;br /&gt;
&lt;br /&gt;
        final String adminEmail = &amp;quot;oxadmin@example.com&amp;quot;;&lt;br /&gt;
        final String ctxadmname = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        oxadmin.setName(ctxadmname);&lt;br /&gt;
        oxadmin.setPassword(ctxadmpw);&lt;br /&gt;
        oxadmin.setDisplayName(&amp;quot;OX Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setSurName(&amp;quot;OX&amp;quot;);&lt;br /&gt;
        oxadmin.setGivenName(&amp;quot;Admin&amp;quot;);&lt;br /&gt;
        oxadmin.setPrimaryEmail(adminEmail);&lt;br /&gt;
        oxadmin.setEmail1(adminEmail);&lt;br /&gt;
        oxadmin.setDefaultSenderAddress(adminEmail);&lt;br /&gt;
        oxadmin.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        oxadmin.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            ResellerContext ret = contextport.createModuleAccessByName(ctx, oxadmin, &amp;quot;groupware_premium&amp;quot;, creds, null);&lt;br /&gt;
            System.out.println(&amp;quot;created context with id=&amp;quot; + ret.getId());&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;existing contexts:&amp;quot;);&lt;br /&gt;
            List&amp;lt;ResellerContext&amp;gt; allctxs = contextport.listAll(creds);&lt;br /&gt;
            for(final ResellerContext c : allctxs) {&lt;br /&gt;
                System.out.println(c.getName() + &amp;quot; with id=&amp;quot; + c.getId());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            System.in.read();&lt;br /&gt;
&lt;br /&gt;
            System.out.println(&amp;quot;deleting created context again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            contextport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ContextExistsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User creation =====&lt;br /&gt;
&lt;br /&gt;
The client below utilizes all SOAP services we have created so far.&lt;br /&gt;
&lt;br /&gt;
The essential parts of the code are&lt;br /&gt;
&lt;br /&gt;
* use OXResellerContextService to find out the ID of the context you want to create users&lt;br /&gt;
* create users using OXResellerUserService&lt;br /&gt;
* use one of the moduleaccess values as documented [[#Create_users|earlier]]&lt;br /&gt;
* use setMailQuota from OXaaSService to set each users mail quota individually&lt;br /&gt;
* use existsLogin from OXaaSService to check in advance of a login already exists&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.ExistsLoginFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.extra.SetMailQuotaFaultException;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.Delete;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class MyUserClientExample {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
        User auser = new User();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        final String userEmail = &amp;quot;auser@example.com&amp;quot;;&lt;br /&gt;
        auser.setName(&amp;quot;auser&amp;quot;);&lt;br /&gt;
        auser.setPassword(&amp;quot;secret&amp;quot;);&lt;br /&gt;
        auser.setDisplayName(&amp;quot;My User&amp;quot;);&lt;br /&gt;
        auser.setSurName(&amp;quot;My&amp;quot;);&lt;br /&gt;
        auser.setGivenName(&amp;quot;User&amp;quot;);&lt;br /&gt;
        auser.setPrimaryEmail(userEmail);&lt;br /&gt;
        auser.setEmail1(userEmail);&lt;br /&gt;
        auser.setDefaultSenderAddress(userEmail);&lt;br /&gt;
        auser.setLanguage(&amp;quot;en_US&amp;quot;);&lt;br /&gt;
        auser.setTimezone(&amp;quot;Europe/Berlin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            // create the user via OXResellerUserService&lt;br /&gt;
            User ret = userport.createByModuleAccessName(ctx, auser, &amp;quot;groupware_premium&amp;quot;, creds);&lt;br /&gt;
            System.out.println(&amp;quot;created user with id=&amp;quot; + ret.getId());&lt;br /&gt;
            &lt;br /&gt;
            // set mail quota for that user using OXaaSService&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(ctxadmname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(ctxadmpw);&lt;br /&gt;
            oxaasport.setMailQuota(ctxRet.getId(), ret.getId(), 1000l, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            // check whether the login for the user has been created within my subadmin namespace&lt;br /&gt;
            // NOTE: this check should be used beforehand usually: check whether login exists and then create it if not&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasAdminCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasAdminCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasAdminCreds.setPassword(subadminpw);&lt;br /&gt;
            if( oxaasport.existsLogin(&amp;quot;auser&amp;quot;, oxaasAdminCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;all ok, user login has been created&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            System.in.read();&lt;br /&gt;
            &lt;br /&gt;
            System.out.println(&amp;quot;deleting created user again&amp;quot;);&lt;br /&gt;
            Delete del = new Delete();&lt;br /&gt;
            del.setAuth(creds);&lt;br /&gt;
            del.setCtx(ctx);&lt;br /&gt;
            del.setUser(ret);&lt;br /&gt;
            userport.delete(del);&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (SetMailQuotaFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ExistsLoginFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Email (alias) management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage email aliases and shared domains.&lt;br /&gt;
The essential information is:&lt;br /&gt;
&lt;br /&gt;
* if you want to change the email address of a user, you have to add the new address to the list of aliases&lt;br /&gt;
* when you want to change individual settings of a user, only send the changed settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateSharedDomainFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
import com.openexchange.oxaas.user.Change;&lt;br /&gt;
import com.openexchange.oxaas.user.DatabaseUpdateExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.DuplicateExtensionExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidCredentialsExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.InvalidDataExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchContextExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.NoSuchUserExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserService;&lt;br /&gt;
import com.openexchange.oxaas.user.OXResellerUserServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.user.RemoteExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.StorageExceptionException;&lt;br /&gt;
import com.openexchange.oxaas.user.reseller.soap.dataobjects.ResellerContext;&lt;br /&gt;
import com.openexchange.oxaas.user.rmi.dataobjects.Credentials;&lt;br /&gt;
import com.openexchange.oxaas.user.soap.dataobjects.User;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSAliasManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName USER_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerUserService&amp;quot;);&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String ctxadmname   = &amp;quot;oxadmin&amp;quot;;&lt;br /&gt;
        final String ctxadmpw     = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        Credentials creds = new Credentials();&lt;br /&gt;
        ResellerContext ctx = new ResellerContext();&lt;br /&gt;
&lt;br /&gt;
        OXResellerUserService userservice = new OXResellerUserService(OXResellerUserService.WSDL_LOCATION, USER_SERVICE_NAME);&lt;br /&gt;
        OXResellerUserServicePortType userport = userservice.getOXResellerUserServiceHttpSoap12Endpoint();&lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        creds.setLogin(ctxadmname);&lt;br /&gt;
        creds.setPassword(ctxadmpw);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
            ctx.setId(ctxRet.getId());&lt;br /&gt;
&lt;br /&gt;
            /*&lt;br /&gt;
             * now we want to add an alias to the user &amp;quot;auser&amp;quot;&lt;br /&gt;
             */&lt;br /&gt;
            User auser = new User();&lt;br /&gt;
            auser.setName(userlogin);&lt;br /&gt;
            User ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            List&amp;lt;String&amp;gt; aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            // now add another one&lt;br /&gt;
            aliases.add(&amp;quot;sales@example.com&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // we also want to add an alias within a shared domain&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            /*&lt;br /&gt;
             * Note: we can run this method as often as we want, it will ONLY return an error in case we want to add a shared domain&lt;br /&gt;
             * that is already bound to another subadmin/customer&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createSharedDomain(&amp;quot;shared.net&amp;quot;, oxaasCtxCreds);&lt;br /&gt;
            aliases.add(&amp;quot;me@shared.net&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            // store changes&lt;br /&gt;
            // we need to created a clean user instance since we cannot just store back the returned user&lt;br /&gt;
            User changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            Change change = new Change();&lt;br /&gt;
            change.setAuth(creds);&lt;br /&gt;
            change.setCtx(ctx);&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
            &lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * now changing the users email address:&lt;br /&gt;
             * to do that, we have to do the following:&lt;br /&gt;
             * 1. add the new email address to the aliases, if not yet present&lt;br /&gt;
             * 2. change the email address in email1, defaultsenderaddress and primarymail&lt;br /&gt;
             * &lt;br /&gt;
             */&lt;br /&gt;
            String newaddress = &amp;quot;boss@mydomain.com&amp;quot;; // introduce another domain, not shared&lt;br /&gt;
            changeduser = new User();&lt;br /&gt;
            changeduser.setId(ret.getId());&lt;br /&gt;
            changeduser.setEmail1(newaddress);&lt;br /&gt;
            //reuse change from above&lt;br /&gt;
            change.setUsrdata(changeduser);&lt;br /&gt;
            try {&lt;br /&gt;
                // this will throw an error since the new address is not in the aliases&lt;br /&gt;
                userport.change(change);&lt;br /&gt;
            } catch (Exception e) {&lt;br /&gt;
                System.out.println(&amp;quot;ERROR: &amp;quot; + e.getMessage());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now add the new address to the aliases and try again&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            aliases.add(newaddress);&lt;br /&gt;
            changeduser.getAliases().addAll(aliases);&lt;br /&gt;
            userport.change(change);&lt;br /&gt;
&lt;br /&gt;
            // control the result&lt;br /&gt;
            ret = userport.getData(ctx, auser, creds);&lt;br /&gt;
            aliases = ret.getAliases();&lt;br /&gt;
            // list all mail aliases of that user&lt;br /&gt;
            System.out.println(&amp;quot;User has the following alias(es):&amp;quot; + aliases);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DatabaseUpdateExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (NoSuchUserExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateSharedDomainFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Catchall account management =====&lt;br /&gt;
&lt;br /&gt;
The next example shows how to manage catchall accounts.&lt;br /&gt;
Please take into account that this is not necessarily enabled for your account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.openexchange.oxaas.myclient;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.namespace.QName;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextService;&lt;br /&gt;
import com.openexchange.oxaas.context.OXResellerContextServicePortType;&lt;br /&gt;
import com.openexchange.oxaas.extra.CreateDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DeleteDomainCatchallFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.DomainCatchall;&lt;br /&gt;
import com.openexchange.oxaas.extra.ListDomainCatchallsFaultException;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService;&lt;br /&gt;
import com.openexchange.oxaas.extra.OXaaSService_Service;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Example SOAP client for OXaaS OXResellerUserService&lt;br /&gt;
 * &lt;br /&gt;
 * Create users in a context&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
public class OXaaSCatchAllManagement {&lt;br /&gt;
&lt;br /&gt;
    private static final QName CONTEXT_SERVICE_NAME = new QName(&amp;quot;http://soap.reseller.admin.openexchange.com&amp;quot;, &amp;quot;OXResellerContextService&amp;quot;);&lt;br /&gt;
    private static final QName OXAAS_SERVICE_NAME = new QName(&amp;quot;http://soap.oxaas.admin.openexchange.com/&amp;quot;, &amp;quot;OXaaSService&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        final String subadminname = &amp;quot;mysubadmin&amp;quot;;&lt;br /&gt;
        final String subadminpw   = &amp;quot;secret&amp;quot;;&lt;br /&gt;
        final String userlogin    = &amp;quot;auser&amp;quot;;&lt;br /&gt;
        final String ctxname      = subadminname + &amp;quot;_myctx&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        OXResellerContextService contextservice = new OXResellerContextService(OXResellerContextService.WSDL_LOCATION, CONTEXT_SERVICE_NAME);&lt;br /&gt;
        OXResellerContextServicePortType contextport = contextservice.getOXResellerContextServiceHttpSoap11Endpoint();&lt;br /&gt;
        OXaaSService_Service oxaasservice = new OXaaSService_Service(OXaaSService_Service.WSDL_LOCATION, OXAAS_SERVICE_NAME);&lt;br /&gt;
        OXaaSService oxaasport = oxaasservice.getOXaaSServiceSOAP();  &lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // We need to use the ResellerContextService SOAP client stub to retrieve the context id&lt;br /&gt;
        com.openexchange.oxaas.context.rmi.dataobjects.Credentials ctxCreds = new com.openexchange.oxaas.context.rmi.dataobjects.Credentials();&lt;br /&gt;
        com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxCtx = new com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext();&lt;br /&gt;
        ctxCreds.setLogin(subadminname);&lt;br /&gt;
        ctxCreds.setPassword(subadminpw);&lt;br /&gt;
        ctxCtx.setName(ctxname);&lt;br /&gt;
&lt;br /&gt;
        try {&lt;br /&gt;
            // we only have the name of the context, so we need to retrieve its id, first using ResellerContextService&lt;br /&gt;
            com.openexchange.oxaas.context.reseller.soap.dataobjects.ResellerContext ctxRet = contextport.getData(ctxCtx, ctxCreds);&lt;br /&gt;
&lt;br /&gt;
            com.openexchange.oxaas.extra.Credentials oxaasCtxCreds = new com.openexchange.oxaas.extra.Credentials();&lt;br /&gt;
            oxaasCtxCreds.setLogin(subadminname);&lt;br /&gt;
            oxaasCtxCreds.setPassword(subadminpw);&lt;br /&gt;
            &lt;br /&gt;
            /*&lt;br /&gt;
             * Note: this will throw an error&lt;br /&gt;
             * oxaas_catchall_domain capability not available for context XXX, user YYY in brand ZZZ&lt;br /&gt;
             * unless you have domain catchall in your contract&lt;br /&gt;
             */&lt;br /&gt;
            oxaasport.createDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
            &lt;br /&gt;
            for(final DomainCatchall dc : oxaasport.listDomainCatchalls(ctxRet.getId(), oxaasCtxCreds) ) {&lt;br /&gt;
                System.out.println(&amp;quot;Catchall account for domain &amp;quot; + dc.getDomain() + &amp;quot; is &amp;quot; + dc.getLogin());&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            // cleanup&lt;br /&gt;
            oxaasport.deleteDomainCatchall(ctxRet.getId(), &amp;quot;example.com&amp;quot;, userlogin, oxaasCtxCreds);&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidDataExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.NoSuchContextExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.DuplicateExtensionExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.InvalidCredentialsExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.RemoteExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (com.openexchange.oxaas.context.StorageExceptionException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (ListDomainCatchallsFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (DeleteDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        } catch (CreateDomainCatchallFaultException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl ===&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSContext ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSContext.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: createOXaaSUser ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/createOXaaSUser.pl&lt;br /&gt;
&lt;br /&gt;
==== Standalone example: changeOXaaSUserPermissions ====&lt;br /&gt;
&lt;br /&gt;
http://software.open-xchange.com/products/appsuite/doc/oxasservice/changeOXaaSUserPermissions.pl&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== OXaas APS(1.2) package ====&lt;br /&gt;
&lt;br /&gt;
Just download the APS package as mentioned [[#Reference_implementation|here]]. When you extract the zip file, you will find&lt;br /&gt;
the perl code within the directory &amp;lt;tt&amp;gt;scripts&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;OXSOAP.pm: SOAP Wrapper functions&lt;br /&gt;
;configure-alias.pl: Mail alias management&lt;br /&gt;
;configure-catchall.pl: Catchall mail alias management&lt;br /&gt;
;configure-mbox.pl: User management&lt;br /&gt;
;configure.pl: Context management&lt;br /&gt;
;verify-account.pl: check for login existence (existsLogin)&lt;br /&gt;
;verify-catchall.pl: check for catchall existence&lt;br /&gt;
;verify-shared.pl: shared mail alias checks&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Introduction_to_the_HTTP_API&amp;diff=24639</id>
		<title>AppSuite:Introduction to the HTTP API</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Introduction_to_the_HTTP_API&amp;diff=24639"/>
		<updated>2019-05-02T05:58:30Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The content on this page has moved to https://documentation.open-xchange.com/components/middleware/http/latest/index.html.&lt;br /&gt;
&lt;br /&gt;
Note: Open-Xchange is in the process of migrating all its technical documentation to a new and improved documentation system (documentation.open-xchange.com). Please note as the migration takes place more information will be available on the new system and less on this system. Thank you for your understanding during this period of transition.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:CrossContextDatabase&amp;diff=24232</id>
		<title>AppSuite:CrossContextDatabase</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:CrossContextDatabase&amp;diff=24232"/>
		<updated>2018-08-30T11:17:36Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;title&amp;quot;&amp;gt;Cross-context database&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{VersionFrom|7.8.0}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
For storing data across context boundaries, a so called &amp;quot;global&amp;quot; database is used by the server. For example, such shared data could be information about guest users or data for registered OAuth applications. This article gives an overview about the basic concepts and how to setup a global database.&lt;br /&gt;
&lt;br /&gt;
== Register databases ==&lt;br /&gt;
&lt;br /&gt;
As a prerequisite, a global database needs to be registered in the Open-Xchange server's configuration database. At the storage layer, global databases are handled just like the ordinary &amp;lt;tt&amp;gt;context&amp;lt;/tt&amp;gt; databases storing all the existing groupware data. Therefore, the same underlying technologies can be used for replication like master/slave- or Galera-based setups, as well as registering additional database pools for sharding in very large installations. &lt;br /&gt;
&lt;br /&gt;
So, much similar to the groupware databases that store context-internal data, a new global database can be registered using the &amp;lt;tt&amp;gt;registerdatabase&amp;lt;/tt&amp;gt; commandline tool. To prevent the registered database being picked up for groupware data, set the &amp;lt;tt&amp;gt;maxunit&amp;lt;/tt&amp;gt; argument to &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 $ /opt/open-xchange/sbin/registerdatabase -A oxadminmaster -P admin_master_password --name oxglobal --hostname localhost --dbuser openexchange --dbpasswd db_password --master true --maxunit 0&lt;br /&gt;
 database 8 registered&lt;br /&gt;
&lt;br /&gt;
Remember the returned database identifier, &amp;lt;tt&amp;gt;8&amp;lt;/tt&amp;gt; in the above example, we'll need it at a later stage.&lt;br /&gt;
&lt;br /&gt;
Optionally, in case a database slave should be added, you can register it afterwards by specifying the database identifier as &amp;lt;tt&amp;gt;masterid&amp;lt;/tt&amp;gt; like follows:&lt;br /&gt;
&lt;br /&gt;
 $ /opt/open-xchange/sbin/registerdatabase -A oxadminmaster -P admin_master_password --name oxglobal_slave --hostname slave_host --dbuser openexchange --dbpasswd db_password --master false --maxunit 0 --masterid=8&lt;br /&gt;
 database 9 registered&lt;br /&gt;
&lt;br /&gt;
For smaller or test environments, it's also possible to re-use a previously registered groupware database for cross-context data, i.e. any database marked as &amp;lt;tt&amp;gt;master&amp;lt;/tt&amp;gt; by the &amp;lt;tt&amp;gt;listdatabase&amp;lt;/tt&amp;gt; utility may be used. Please note that all cross-context data is not accounted when calculating the database weight during context creation.&lt;br /&gt;
&lt;br /&gt;
== Context Groups ==&lt;br /&gt;
&lt;br /&gt;
As already mentioned, data inside the global database is shared between and available to all contexts in the installation. For setups serving multiple different &amp;quot;brands&amp;quot; or &amp;quot;domains&amp;quot;, this may not be the desired behavior, so that an additional level of data separation is needed for cross-context data. Therefore, one or more contexts can be classified into a specific &amp;quot;group&amp;quot;. The association with the group is done by assigning the property &amp;lt;tt&amp;gt;com.openexchange.context.group&amp;lt;/tt&amp;gt; to a context via config cascade. A context may only be part of one group, contexts without group association automatically fall into the &amp;quot;default&amp;quot; group. &lt;br /&gt;
&lt;br /&gt;
As an example, a hoster is selling his hosted e-mail services under two different brands, called &amp;quot;Clever Hosting&amp;quot; and &amp;quot;Smart Hosting&amp;quot;. Each customer that registered an account at &amp;quot;Clever Hosting&amp;quot; now is put into the context group &amp;quot;clever_hosting&amp;quot; by setting the property &amp;lt;tt&amp;gt;com.openexchange.context.group&amp;lt;/tt&amp;gt; at any level of the config cascade, e.g. during provisioning when creating the context like: &lt;br /&gt;
&lt;br /&gt;
 $ /opt/open-xchange/sbin/createcontext [...] --config/com.openexchange.context.group=clever_hosting&lt;br /&gt;
&lt;br /&gt;
Or, if you already tagged your contexts with different taxonomy types (like &amp;lt;tt&amp;gt;clever&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;smart&amp;lt;/tt&amp;gt; in our example), the assignment to a context group can also be achieved at &amp;quot;ContextSet&amp;quot; level inside an &amp;lt;tt&amp;gt;.yml&amp;lt;/tt&amp;gt;-file of your &amp;lt;tt&amp;gt;contextSets&amp;lt;/tt&amp;gt; definitions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clever_group:&lt;br /&gt;
    withTags: clever&lt;br /&gt;
    com.openexchange.context.group: clever_hosting&lt;br /&gt;
    ui/product/name: &amp;quot;Clever Hosting&amp;quot;&lt;br /&gt;
    [...]&lt;br /&gt;
 &lt;br /&gt;
smart_group:&lt;br /&gt;
    withTags: smart&lt;br /&gt;
    com.openexchange.context.group: smart_hosting&lt;br /&gt;
    ui/product/name: &amp;quot;Smart Hosting&amp;quot;&lt;br /&gt;
    [...]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the global database, the context group identifier serves as differentiating key for various data. For example, data of a guest user that was invited to a share in one context of a group can be used throughout all other contexts of the same group. Or, there may be a different set of registered OAuth applications available for each context group. Having contexts separated into different groups also allows to use different global databases as defined in the additional sections of the configuration file &amp;lt;tt&amp;gt;globaldb.yml&amp;lt;/tt&amp;gt;. The next chapter describes the global database configuration file in more detail.&lt;br /&gt;
&lt;br /&gt;
== Configure databases ==&lt;br /&gt;
&lt;br /&gt;
Global databases are defined in the configuration file &amp;lt;tt&amp;gt;globaldb.yml&amp;lt;/tt&amp;gt;. It mainly serves the purpose to map registered global databases to context groups. In case no advanced context grouping is necessary, e.g. because there's only a single brand in the installation, it's sufficient to supply the identifier of the previously registered master database, see [[#Register databases|Register databases]] above, inside the &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; section of the configuration file. For example, if the identifier of the global database master is &amp;lt;tt&amp;gt;8&amp;lt;/tt&amp;gt;, the section would look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
default:&lt;br /&gt;
    groups: [default]&lt;br /&gt;
    id: 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would lead to all cross-context data being stored at this database, assigning distinguished context groups as described in [[#Context Groups|Context Groups]] is not required. &lt;br /&gt;
&lt;br /&gt;
If there are multiple context groups, those can be directed to a specific global database by adding their names to the &amp;lt;tt&amp;gt;groups&amp;lt;/tt&amp;gt; property of a configuration section. For example, if the groups &amp;lt;tt&amp;gt;smart_hosting&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;clever_hosting&amp;lt;/tt&amp;gt; should use database &amp;lt;tt&amp;gt;8&amp;lt;/tt&amp;gt;, too, one could define:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
default:&lt;br /&gt;
    groups: [default,smart_hosting,clever_hosting]&lt;br /&gt;
    id: 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Removing the default group name &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; from the groups list is not recommended, and should only be done if you can ensure that each context of the installation has it's group assignment defined correctly in the property &amp;lt;tt&amp;gt;com.openexchange.context.group&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Having contexts separated into different groups also allows to use different global databases as defined in the additional sections of the configuration file &amp;lt;tt&amp;gt;globaldb.yml&amp;lt;/tt&amp;gt;. Since context groups are bound to a configuration section by specifying the group name in the &amp;quot;groups&amp;quot; array, and each configuration section may target another global database, in theory there could be as much global databases as there are defined context groups. For example, to enforce data from the context groups &amp;lt;tt&amp;gt;smart_hosting&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;clever_hosting&amp;lt;/tt&amp;gt; being stored at separate databases, the following configuration sections would route them to the database identifiers &amp;lt;tt&amp;gt;8&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;14&amp;lt;/tt&amp;gt; respectively:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clever:&lt;br /&gt;
    groups: [clever_hosting]&lt;br /&gt;
    id: 8&lt;br /&gt;
&lt;br /&gt;
smart:&lt;br /&gt;
    groups: [smart_hosting]&lt;br /&gt;
    id: 14&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reload global db configuration ==&lt;br /&gt;
&lt;br /&gt;
After updating the globaldb.yml you have to reload the server configuration by using /opt/open-xchange/sbin/reloadconfiguration command line tool.&lt;br /&gt;
&lt;br /&gt;
[[Category: AppSuite]]&lt;br /&gt;
[[Category: Administrator]]&lt;br /&gt;
[[Category: Database]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Open-Xchange_Installation_Guide_for_Debian_8.0&amp;diff=24228</id>
		<title>AppSuite:Open-Xchange Installation Guide for Debian 8.0</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Open-Xchange_Installation_Guide_for_Debian_8.0&amp;diff=24228"/>
		<updated>2018-08-21T13:26:35Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.8.4, 7.10.x}}&lt;br /&gt;
&lt;br /&gt;
= OX App Suite on Debian GNU/Linux 8.0 =&lt;br /&gt;
&lt;br /&gt;
{{QuickInstIntro|release=appsuite}}&lt;br /&gt;
&lt;br /&gt;
= Requirements =&lt;br /&gt;
&lt;br /&gt;
* Plain installed Debian GNU/Linux 8.0, no graphical tools required&lt;br /&gt;
* A supported Java Virtual Machine ([[AppSuite:OX_System_Requirements#Java|learn more]])&lt;br /&gt;
* A working internet connection&lt;br /&gt;
* vim is not installed by default on Debian. If you want to copy &amp;amp; paste the commands from this article into a shell window, you need to &amp;lt;code&amp;gt;apt-get install vim&amp;lt;/code&amp;gt; first.&lt;br /&gt;
&lt;br /&gt;
= Debian Jessie backports repository for OpenJDK 8 (only for AppSuite 7.10.0) =&lt;br /&gt;
&lt;br /&gt;
OX App Suite v7.10.0 requires OpenJDK 8 while for previous OX App Suite versions Java version 7 was required. Unfortunately Debian Jessie does not contain Java version 8. Therefore we need to install it from the Debian Jessie backports repositories to be able to run OX App Suite v7.10.0 on Debian Jessie.&lt;br /&gt;
&lt;br /&gt;
Add the repository for Debian Jessie backports.&lt;br /&gt;
&lt;br /&gt;
 $ cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/apt/sources.list.d/backports.list&lt;br /&gt;
 deb http://&amp;lt;your debian mirror&amp;gt;/debian jessie-backports main&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
Furthermore you need to allow the Debian package manager to install the OpenJDK 8 related packages from the Debian Jessie backports repository. Normally these packages have less priority and are not chosen as installation candidates. Raise the priority as shown below:&lt;br /&gt;
&lt;br /&gt;
 $ cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/apt/preferences.d/ca-certificates-java.pref&lt;br /&gt;
 Package: ca-certificates-java&lt;br /&gt;
 Pin: release a=jessie-backports&lt;br /&gt;
 Pin-Priority: 501&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
Now the package manager is able to choose OpenJDK 8 from the Debian Jessie backports.&lt;br /&gt;
&lt;br /&gt;
= Database installation =&lt;br /&gt;
&lt;br /&gt;
Please consult our [[OXLoadBalancingClustering_Database#Standalone_database_setup|database installation instructions]] for information on how to install a database on the local system.&lt;br /&gt;
&lt;br /&gt;
Before proceeding, make sure the local machine has got a working MySQL service in one of the supported versions / flavors with the configuration / tunings applied as mentioned on our [[My.cnf|corresponding page]].&lt;br /&gt;
&lt;br /&gt;
{{AddReposDebian|debname=jessie|debnameox=DebianJessie|release=appsuite}}&lt;br /&gt;
&lt;br /&gt;
= Updating repositories and install packages =&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to import the Open-Xchange build key to your package systems trusted keyring in order to make sure only Open-Xchange packages with valid signing are installed on the system. Otherwise you'll encounter warnings about untrusted package sources. To import the Open-Xchange buildkey, please refer to this quick guide: [[Importing_OX_Buildkey#Importing_key_into_apt_based_systems|Importing OX Buildkey]].&lt;br /&gt;
&lt;br /&gt;
Reload the package index. This will download the package descriptions available at the software repositories and will enable the Open-Xchange repository as a valid source for signed packages:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
&lt;br /&gt;
The following command starts the download and installation process of all required package for Open-Xchange deployment:&lt;br /&gt;
&lt;br /&gt;
{{OXPackageInstallation|installer=apt-get|javavendor=sun|release=appsuite}}&lt;br /&gt;
&lt;br /&gt;
{{OXConfiguration}}&lt;br /&gt;
&lt;br /&gt;
{{oxinstaller|connector=http}}&lt;br /&gt;
&lt;br /&gt;
After initializing the configuration, restart the Open-Xchange Administration service by executing:&lt;br /&gt;
&lt;br /&gt;
 $ systemctl restart open-xchange&lt;br /&gt;
&lt;br /&gt;
{{OXRegister|globaldb=true}}&lt;br /&gt;
&lt;br /&gt;
= Configure services =&lt;br /&gt;
&lt;br /&gt;
{{ApacheOXModsDebian|connector=http|extramods=lbmethod_byrequests}}&lt;br /&gt;
&lt;br /&gt;
{{Template:ApacheAppSuiteConf|connector=http|connectorConf=/etc/apache2/conf-available/proxy_http.conf|apacheconf=/etc/apache2/sites-enabled/000-default.conf|docroot=/var/www/html|loadmodule=|syncProxyName=eas_oxcluster}}&lt;br /&gt;
&lt;br /&gt;
Enable the proxy configuration&lt;br /&gt;
&lt;br /&gt;
 $ a2enconf proxy_http.conf&lt;br /&gt;
&lt;br /&gt;
After the configuration is done, restart the Apache webserver&lt;br /&gt;
&lt;br /&gt;
 $ systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
== Upgrade from Debian 7 ==&lt;br /&gt;
&lt;br /&gt;
If you updated from Debian 7 to Debian 8 the proxy_http.conf file is still located in the &amp;lt;tt&amp;gt;conf.d&amp;lt;/tt&amp;gt; directory which is not read in Debian 8. So you have to move the file to &amp;lt;tt&amp;gt;conf-available&amp;lt;/tt&amp;gt; and execute &amp;lt;tt&amp;gt;a2enconf proxy_http&amp;lt;/tt&amp;gt; afterwards.&lt;br /&gt;
&lt;br /&gt;
== Apache Setting for more concurrent Connections ==&lt;br /&gt;
&lt;br /&gt;
By default apache2 is configured to support 150 concurrent connections. This forces all parallel requests beyond that limit to wait. Especially if, for example, active sync clients maintain a permanent connection for push events to arrive. The following article explains how that can be done&lt;br /&gt;
&lt;br /&gt;
[[Tune_apache2_for_more_concurrent_connections|Apache Setting for more concurrent Connections]]&lt;br /&gt;
&lt;br /&gt;
{{ContextUserAndLogs}}&lt;br /&gt;
&lt;br /&gt;
[[Category: AppSuite]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Open-Xchange_Installation_Guide_for_Debian_8.0&amp;diff=24226</id>
		<title>AppSuite:Open-Xchange Installation Guide for Debian 8.0</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Open-Xchange_Installation_Guide_for_Debian_8.0&amp;diff=24226"/>
		<updated>2018-08-16T07:59:01Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.8.4, 7.10.x}}&lt;br /&gt;
&lt;br /&gt;
= OX App Suite on Debian GNU/Linux 8.0 =&lt;br /&gt;
&lt;br /&gt;
{{QuickInstIntro|release=appsuite}}&lt;br /&gt;
&lt;br /&gt;
= Requirements =&lt;br /&gt;
&lt;br /&gt;
* Plain installed Debian GNU/Linux 8.0, no graphical tools required&lt;br /&gt;
* A supported Java Virtual Machine ([http://oxpedia.org/wiki/index.php?title=AppSuite:OX_System_Requirements#Server_Platforms learn more])&lt;br /&gt;
* A working internet connection&lt;br /&gt;
* vim is not installed by default on Debian. If you want to copy &amp;amp; paste the commands from this article into a shell window, you need to &amp;lt;code&amp;gt;apt-get install vim&amp;lt;/code&amp;gt; first.&lt;br /&gt;
&lt;br /&gt;
= Debian Jessie backports repository for OpenJDK 8 (only for AppSuite 7.10.0) =&lt;br /&gt;
&lt;br /&gt;
OX App Suite v7.10.0 requires OpenJDK 8 while for previous OX App Suite versions Java version 7 was required. Unfortunately Debian Jessie does not contain Java version 8. Therefore we need to install it from the Debian Jessie backports repositories to be able to run OX App Suite v7.10.0 on Debian Jessie.&lt;br /&gt;
&lt;br /&gt;
Add the repository for Debian Jessie backports.&lt;br /&gt;
&lt;br /&gt;
 $ cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/apt/sources.list.d/backports.list&lt;br /&gt;
 deb http://&amp;lt;your debian mirror&amp;gt;/debian jessie-backports main&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
Furthermore you need to allow the Debian package manager to install the OpenJDK 8 related packages from the Debian Jessie backports repository. Normally these packages have less priority and are not chosen as installation candidates. Raise the priority as shown below:&lt;br /&gt;
&lt;br /&gt;
 $ cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/apt/preferences.d/ca-certificates-java.pref&lt;br /&gt;
 Package: ca-certificates-java&lt;br /&gt;
 Pin: release a=jessie-backports&lt;br /&gt;
 Pin-Priority: 501&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
Now the package manager is able to choose OpenJDK 8 from the Debian Jessie backports.&lt;br /&gt;
&lt;br /&gt;
= Database installation =&lt;br /&gt;
&lt;br /&gt;
Please consult our [[OXLoadBalancingClustering_Database#Standalone_database_setup|database installation instructions]] for information on how to install a database on the local system.&lt;br /&gt;
&lt;br /&gt;
Before proceeding, make sure the local machine has got a working MySQL service in one of the supported versions / flavors with the configuration / tunings applied as mentioned on our [[My.cnf|corresponding page]].&lt;br /&gt;
&lt;br /&gt;
{{AddReposDebian|debname=jessie|debnameox=DebianJessie|release=appsuite}}&lt;br /&gt;
&lt;br /&gt;
= Updating repositories and install packages =&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to import the Open-Xchange build key to your package systems trusted keyring in order to make sure only Open-Xchange packages with valid signing are installed on the system. Otherwise you'll encounter warnings about untrusted package sources. To import the Open-Xchange buildkey, please refer to this quick guide: [[Importing_OX_Buildkey#Importing_key_into_apt_based_systems|Importing OX Buildkey]].&lt;br /&gt;
&lt;br /&gt;
Reload the package index. This will download the package descriptions available at the software repositories and will enable the Open-Xchange repository as a valid source for signed packages:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
&lt;br /&gt;
The following command starts the download and installation process of all required package for Open-Xchange deployment:&lt;br /&gt;
&lt;br /&gt;
{{OXPackageInstallation|installer=apt-get|javavendor=sun|release=appsuite}}&lt;br /&gt;
&lt;br /&gt;
{{OXConfiguration}}&lt;br /&gt;
&lt;br /&gt;
{{oxinstaller|connector=http}}&lt;br /&gt;
&lt;br /&gt;
After initializing the configuration, restart the Open-Xchange Administration service by executing:&lt;br /&gt;
&lt;br /&gt;
 $ systemctl restart open-xchange&lt;br /&gt;
&lt;br /&gt;
{{OXRegister|globaldb=true}}&lt;br /&gt;
&lt;br /&gt;
= Configure services =&lt;br /&gt;
&lt;br /&gt;
{{ApacheOXModsDebian|connector=http|extramods=lbmethod_byrequests}}&lt;br /&gt;
&lt;br /&gt;
{{Template:ApacheAppSuiteConf|connector=http|connectorConf=/etc/apache2/conf-available/proxy_http.conf|apacheconf=/etc/apache2/sites-enabled/000-default.conf|docroot=/var/www/html|loadmodule=|syncProxyName=eas_oxcluster}}&lt;br /&gt;
&lt;br /&gt;
Enable the proxy configuration&lt;br /&gt;
&lt;br /&gt;
 $ a2enconf proxy_http.conf&lt;br /&gt;
&lt;br /&gt;
After the configuration is done, restart the Apache webserver&lt;br /&gt;
&lt;br /&gt;
 $ systemctl restart apache2&lt;br /&gt;
&lt;br /&gt;
== Upgrade from Debian 7 ==&lt;br /&gt;
&lt;br /&gt;
If you updated from Debian 7 to Debian 8 the proxy_http.conf file is still located in the &amp;lt;tt&amp;gt;conf.d&amp;lt;/tt&amp;gt; directory which is not read in Debian 8. So you have to move the file to &amp;lt;tt&amp;gt;conf-available&amp;lt;/tt&amp;gt; and execute &amp;lt;tt&amp;gt;a2enconf proxy_http&amp;lt;/tt&amp;gt; afterwards.&lt;br /&gt;
&lt;br /&gt;
== Apache Setting for more concurrent Connections ==&lt;br /&gt;
&lt;br /&gt;
By default apache2 is configured to support 150 concurrent connections. This forces all parallel requests beyond that limit to wait. Especially if, for example, active sync clients maintain a permanent connection for push events to arrive. The following article explains how that can be done&lt;br /&gt;
&lt;br /&gt;
[[Tune_apache2_for_more_concurrent_connections|Apache Setting for more concurrent Connections]]&lt;br /&gt;
&lt;br /&gt;
{{ContextUserAndLogs}}&lt;br /&gt;
&lt;br /&gt;
[[Category: AppSuite]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:UpdatingOXPackages&amp;diff=24225</id>
		<title>AppSuite:UpdatingOXPackages</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:UpdatingOXPackages&amp;diff=24225"/>
		<updated>2018-08-16T07:00:26Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;title&amp;quot;&amp;gt;Updating OX App Suite packages&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Synopsys'': This article describes how to update OX App Suite packages from one service pack to another.&lt;br /&gt;
&lt;br /&gt;
== Warnings ==&lt;br /&gt;
&lt;br /&gt;
Before we begin, here are several things that you should keep in mind:&lt;br /&gt;
* If you are '''updating a cluster, please do it one node after the other'''. Turn the node off, update, turn it on again, make sure it works in the cluster. Have a look here, too: [[Running_a_cluster#Upgrading_a_single_Node|Upgrading a single node]]&lt;br /&gt;
* If you don't have a cluster of OX nodes, then your complete installation needs to be taken down temporarily.&lt;br /&gt;
* Please '''update the backend before the frontend'''.&lt;br /&gt;
* Please '''do not restart Open-Xchange during the database update'''. A database update can happen after installing minor or major updates. As soon as the first user tries to log in to the system or if any provisioning action is done, this update starts.&lt;br /&gt;
&lt;br /&gt;
=== Upgrading to 7.8.4 ===&lt;br /&gt;
* During the upgrade to 7.8.4 the existing ''JAVA_XTRAOPTS'' configuration property of the middleware stack in the file ''ox-scriptconf.sh'' will automatically be split up and migrated to a new categories approach. Please have a look at [[AppSuite:MiddlewareStartup#Evaluate_JVM_commandline_options|JVM commandline options]] and review the automatically upgraded configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Upgrading to 7.10.0 ===&lt;br /&gt;
&lt;br /&gt;
* OX App Suite v7.10.0 introduces significant changes regarding the underlying MySQL database system that require special attention in case of upgrades from former versions. Please read [[AppSuite:7_10_Database_Migration]] carefully to familiarize with the details, implications and our proposed upgrade path.&lt;br /&gt;
* v7.10.0 also requires OpenJDK 8. To update or install v7.10.0 on Debian Jessie, follow [[AppSuite:Open-Xchange_Installation_Guide_for_Debian_8.0#Debian_Jessie_backports_repository_for_OpenJDK_8_.28only_for_AppSuite_7.10.0.29|these instructions]].&lt;br /&gt;
&lt;br /&gt;
== How to get updates? ==&lt;br /&gt;
&lt;br /&gt;
OX App Suite updates can be accessed by customers with a valid license.&lt;br /&gt;
&lt;br /&gt;
In addition, you need to configure the [[OXReportClient]].&lt;br /&gt;
&lt;br /&gt;
= Updating OX App Suite Packages =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing Updates ==&lt;br /&gt;
&lt;br /&gt;
A new service pack usually introduces new packages and requires configuration changes. To get all required new packages and configuration changes, the following '''must''' be done when installing updates.&lt;br /&gt;
&lt;br /&gt;
(Please, keep the [[#Warning|warning about backend updates before frontend updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
=== On Debian based distributions ===&lt;br /&gt;
&lt;br /&gt;
==== Debian Jessie ====&lt;br /&gt;
&lt;br /&gt;
Add the following entry to &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/open-xchange.list&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/DebianJessie/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/DebianJessie /&lt;br /&gt;
&lt;br /&gt;
Then run&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get dist-upgrade&lt;br /&gt;
&lt;br /&gt;
Important: In case you are asked in the process if you would like to replace a configuration with the default delivered in the updated package please DO NOT replace but KEEP your existing configuration. In case something needs to be changed mandatorily this will be handled and modified by scripts which run after package installation automatically.&lt;br /&gt;
&lt;br /&gt;
If you want to see, what apt-get is going to do without actually doing it, you can run:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get dist-upgrade -s&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Debian Stretch (valid from v7.10) ====&lt;br /&gt;
&lt;br /&gt;
Add the following entry to &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/open-xchange.list&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/DebianStretch/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/DebianStretch /&lt;br /&gt;
&lt;br /&gt;
Then run&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get dist-upgrade&lt;br /&gt;
&lt;br /&gt;
Important: In case you are asked in the process if you would like to replace a configuration with the default delivered in the updated package please DO NOT replace but KEEP your existing configuration. In case something needs to be changed mandatorily this will be handled and modified by scripts which run after package installation automatically.&lt;br /&gt;
&lt;br /&gt;
If you want to see, what apt-get is going to do without actually doing it, you can run:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get dist-upgrade -s&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== On RPM based distributions ===&lt;br /&gt;
&lt;br /&gt;
==== RHEL6/CentOS6 ====&lt;br /&gt;
&lt;br /&gt;
Add the following entries to &amp;lt;tt&amp;gt;/etc/yum.repos.d/ox.repo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 [ox-updates-appsuiteui]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/RHEL6/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
 &lt;br /&gt;
 [ox-updates-backend]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/RHEL6/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
&lt;br /&gt;
 $ yum upgrade&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
==== RHEL7/CentOS7 ====&lt;br /&gt;
&lt;br /&gt;
Add the following entries to &amp;lt;tt&amp;gt;/etc/yum.repos.d/ox.repo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 [ox-updates-appsuiteui]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/RHEL7/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
 &lt;br /&gt;
 [ox-updates-backend]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/RHEL7/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
&lt;br /&gt;
 $ yum upgrade&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
==== SLES12 ====&lt;br /&gt;
&lt;br /&gt;
Add the updates repository to the repository list:&lt;br /&gt;
&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/SLE_12/ OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/SLE_12/ OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ zypper dup -r OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper dup -r OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
You might need to run&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
&lt;br /&gt;
to update the repository metadata before running ''zypper up''.&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ rcopen-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind.&lt;br /&gt;
&lt;br /&gt;
= Updating OX App Suite Packages for older versions =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing Updates ==&lt;br /&gt;
&lt;br /&gt;
A new service pack usually introduces new packages and requires configuration changes. To get all required new packages and configuration changes, the following '''must''' be done when installing updates.&lt;br /&gt;
&lt;br /&gt;
(Please, keep the [[#Warning|warning about frontend updates before backend updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
=== On Debian based distributions ===&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/open-xchange.list&amp;lt;/tt&amp;gt;. Replace VERSION with the version you are using (e.g. 7.6.2). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/DebianWheezy/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/DebianWheezy/ /&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/DebianJessie/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/DebianJessie /&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/DebianStretch/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/DebianStretch /&lt;br /&gt;
&lt;br /&gt;
Then run&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get dist-upgrade&lt;br /&gt;
&lt;br /&gt;
If you want to see, what apt-get is going to do without actually doing it, you can run:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get dist-upgrade -s&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== On RPM based distributions ===&lt;br /&gt;
&lt;br /&gt;
==== RHEL6/CentOS6 ====&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to &amp;lt;tt&amp;gt;/etc/yum.repos.d/ox.repo&amp;lt;/tt&amp;gt;. Replace VERSION with the version you are using (e.g. 7.4.2, 7.6.0). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 [ox-updates-appsuiteui]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/RHEL6/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
 &lt;br /&gt;
 [ox-updates-backend]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/RHEL6/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
&lt;br /&gt;
 $ yum upgrade&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
==== RHEL7/CentOS7 ====&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to &amp;lt;tt&amp;gt;/etc/yum.repos.d/ox.repo&amp;lt;/tt&amp;gt;. Replace VERSION with the version you are using (e.g. 7.4.2, 7.6.0). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 [ox-updates-appsuiteui]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/RHEL7/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
 &lt;br /&gt;
 [ox-updates-backend]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/RHEL7/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
&lt;br /&gt;
 $ yum upgrade&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
==== SLES 11 ====&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to the repository list. Replace VERSION with the version you are using (e.g. 7.4.2, 7.6.0). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/SLES11/ OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/SLES11/ OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ zypper dup -r OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper dup -r OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
You might need to run&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
&lt;br /&gt;
to update the repository metadata before running ''zypper up''.&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ rcopen-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind.&lt;br /&gt;
&lt;br /&gt;
==== SLES 12 ====&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to the repository list. Replace VERSION with the version you are using (e.g. 7.4.2, 7.6.0). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/SLE_12/ OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/SLE_12/ OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ zypper dup -r OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper dup -r OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
You might need to run&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
&lt;br /&gt;
to update the repository metadata before running ''zypper up''.&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ rcopen-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind.&lt;br /&gt;
&lt;br /&gt;
= Updating UI plugins =&lt;br /&gt;
&lt;br /&gt;
If you update only UI plugins without simultaneously upgrading the core UI packages to a new version, you need to perform an additional step after the update to make the changes visible to users.&lt;br /&gt;
&lt;br /&gt;
The package &amp;lt;tt&amp;gt;open-xchange-appsuite&amp;lt;/tt&amp;gt; contains a timestamp which is different in each version. The JavaScript UI in every user's browser will reload all cached code and data whenever this value changes. Since this value does not change when updating only plugin packages, the value must be changed manually with the following command:&lt;br /&gt;
&lt;br /&gt;
 $ /opt/open-xchange/sbin/touch-appsuite --timestamp=20170101.123400&lt;br /&gt;
&lt;br /&gt;
If you only have one OX node, the parameter &amp;lt;code&amp;gt;--timestamp&amp;lt;/code&amp;gt; can be omitted. It defaults to the current UTC time anyway.&lt;br /&gt;
&lt;br /&gt;
When updating a cluster, the command must use the same timestamp value on every node. Otherwise, browsers will clear their cache and re-download the entire UI code every time load balancer sends them to a different node (i.e. on almost every login). This is also why the timestamps can't be updated automatically: a node doesn't know which value other nodes will pick, which of them are part of the same update, etc.&lt;br /&gt;
&lt;br /&gt;
The quickest way to obtain a value for the timestamp parameter is to run the command with the parameter &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt;. It will then print a help message with the current time as an example. For automation, you can use the output of&lt;br /&gt;
&lt;br /&gt;
 date -u +%Y%m%d.%H%M%S&lt;br /&gt;
&lt;br /&gt;
Again: this value must be computed once, and then the same value must be used on every node in the cluster.&lt;br /&gt;
&lt;br /&gt;
This step can be performed on each node separately after each node has been updated, or on all nodes at once after all nodes have been updated. If Apache has its own set of dedicated nodes, the &amp;lt;tt&amp;gt;touch-appsuite&amp;lt;/tt&amp;gt; call must be performed on the web server nodes, after all corresponding &amp;lt;tt&amp;gt;&amp;lt;plugin&amp;gt;-static&amp;lt;/tt&amp;gt; packages have been updated.&lt;br /&gt;
&lt;br /&gt;
[[Category: OX7]]&lt;br /&gt;
[[Category: AppSuite]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Administrator]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:UpdatingOXPackages&amp;diff=24224</id>
		<title>AppSuite:UpdatingOXPackages</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:UpdatingOXPackages&amp;diff=24224"/>
		<updated>2018-08-16T06:47:15Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;title&amp;quot;&amp;gt;Updating OX App Suite packages&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Synopsys'': This article describes how to update OX App Suite packages from one service pack to another.&lt;br /&gt;
&lt;br /&gt;
== Warnings ==&lt;br /&gt;
&lt;br /&gt;
Before we begin, here are several things that you should keep in mind:&lt;br /&gt;
* If you are '''updating a cluster, please do it one node after the other'''. Turn the node off, update, turn it on again, make sure it works in the cluster. Have a look here, too: [[Running_a_cluster#Upgrading_a_single_Node|Upgrading a single node]]&lt;br /&gt;
* If you don't have a cluster of OX nodes, then your complete installation needs to be taken down temporarily.&lt;br /&gt;
* Please '''update the backend before the frontend'''.&lt;br /&gt;
* Please '''do not restart Open-Xchange during the database update'''. A database update can happen after installing minor or major updates. As soon as the first user tries to log in to the system or if any provisioning action is done, this update starts.&lt;br /&gt;
&lt;br /&gt;
=== Upgrading to 7.8.4 ===&lt;br /&gt;
* During the upgrade to 7.8.4 the existing ''JAVA_XTRAOPTS'' configuration property of the middleware stack in the file ''ox-scriptconf.sh'' will automatically be split up and migrated to a new categories approach. Please have a look at [[AppSuite:MiddlewareStartup#Evaluate_JVM_commandline_options|JVM commandline options]] and review the automatically upgraded configuration file.&lt;br /&gt;
&lt;br /&gt;
=== Upgrading to 7.10.0 ===&lt;br /&gt;
&lt;br /&gt;
* OX App Suite v7.10.0 introduces significant changes regarding the underlying MySQL database system that require special attention in case of upgrades from former versions. Please read http://oxpedia.org/wiki/index.php?title=AppSuite:7_10_Database_Migration carefully to familiarize with the details, implications and our proposed upgrade path.&lt;br /&gt;
* v7.10.0 also requires OpenJDK 8. To update or install v7.10.0 on Debian Jessie, follow [[AppSuite:Open-Xchange_Installation_Guide_for_Debian_8.0#Debian_Jessie_backports_repository_for_OpenJDK_8_.28only_for_AppSuite_7.10.0.29|these instructions]].&lt;br /&gt;
&lt;br /&gt;
== How to get updates? ==&lt;br /&gt;
&lt;br /&gt;
OX App Suite updates can be accessed by customers with a valid license.&lt;br /&gt;
&lt;br /&gt;
In addition, you need to configure the [[OXReportClient]].&lt;br /&gt;
&lt;br /&gt;
= Updating OX App Suite Packages =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing Updates ==&lt;br /&gt;
&lt;br /&gt;
A new service pack usually introduces new packages and requires configuration changes. To get all required new packages and configuration changes, the following '''must''' be done when installing updates.&lt;br /&gt;
&lt;br /&gt;
(Please, keep the [[#Warning|warning about backend updates before frontend updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
=== On Debian based distributions ===&lt;br /&gt;
&lt;br /&gt;
==== Debian Jessie ====&lt;br /&gt;
&lt;br /&gt;
Add the following entry to &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/open-xchange.list&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/DebianJessie/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/DebianJessie /&lt;br /&gt;
&lt;br /&gt;
Then run&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get dist-upgrade&lt;br /&gt;
&lt;br /&gt;
Important: In case you are asked in the process if you would like to replace a configuration with the default delivered in the updated package please DO NOT replace but KEEP your existing configuration. In case something needs to be changed mandatorily this will be handled and modified by scripts which run after package installation automatically.&lt;br /&gt;
&lt;br /&gt;
If you want to see, what apt-get is going to do without actually doing it, you can run:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get dist-upgrade -s&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Debian Stretch (valid from v7.10) ====&lt;br /&gt;
&lt;br /&gt;
Add the following entry to &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/open-xchange.list&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/DebianStretch/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/DebianStretch /&lt;br /&gt;
&lt;br /&gt;
Then run&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get dist-upgrade&lt;br /&gt;
&lt;br /&gt;
Important: In case you are asked in the process if you would like to replace a configuration with the default delivered in the updated package please DO NOT replace but KEEP your existing configuration. In case something needs to be changed mandatorily this will be handled and modified by scripts which run after package installation automatically.&lt;br /&gt;
&lt;br /&gt;
If you want to see, what apt-get is going to do without actually doing it, you can run:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get dist-upgrade -s&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== On RPM based distributions ===&lt;br /&gt;
&lt;br /&gt;
==== RHEL6/CentOS6 ====&lt;br /&gt;
&lt;br /&gt;
Add the following entries to &amp;lt;tt&amp;gt;/etc/yum.repos.d/ox.repo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 [ox-updates-appsuiteui]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/RHEL6/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
 &lt;br /&gt;
 [ox-updates-backend]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/RHEL6/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
&lt;br /&gt;
 $ yum upgrade&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
==== RHEL7/CentOS7 ====&lt;br /&gt;
&lt;br /&gt;
Add the following entries to &amp;lt;tt&amp;gt;/etc/yum.repos.d/ox.repo&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 [ox-updates-appsuiteui]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/RHEL7/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
 &lt;br /&gt;
 [ox-updates-backend]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/RHEL7/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
&lt;br /&gt;
 $ yum upgrade&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
==== SLES12 ====&lt;br /&gt;
&lt;br /&gt;
Add the updates repository to the repository list:&lt;br /&gt;
&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/appsuiteui/updates/SLE_12/ OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/stable/backend/updates/SLE_12/ OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ zypper dup -r OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper dup -r OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
You might need to run&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
&lt;br /&gt;
to update the repository metadata before running ''zypper up''.&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ rcopen-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind.&lt;br /&gt;
&lt;br /&gt;
= Updating OX App Suite Packages for older versions =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing Updates ==&lt;br /&gt;
&lt;br /&gt;
A new service pack usually introduces new packages and requires configuration changes. To get all required new packages and configuration changes, the following '''must''' be done when installing updates.&lt;br /&gt;
&lt;br /&gt;
(Please, keep the [[#Warning|warning about frontend updates before backend updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
=== On Debian based distributions ===&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/open-xchange.list&amp;lt;/tt&amp;gt;. Replace VERSION with the version you are using (e.g. 7.6.2). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/DebianWheezy/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/DebianWheezy/ /&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/DebianJessie/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/DebianJessie /&lt;br /&gt;
&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/DebianStretch/ /&lt;br /&gt;
 deb http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/DebianStretch /&lt;br /&gt;
&lt;br /&gt;
Then run&lt;br /&gt;
&lt;br /&gt;
 $ apt-get update&lt;br /&gt;
 $ apt-get dist-upgrade&lt;br /&gt;
&lt;br /&gt;
If you want to see, what apt-get is going to do without actually doing it, you can run:&lt;br /&gt;
&lt;br /&gt;
 $ apt-get dist-upgrade -s&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== On RPM based distributions ===&lt;br /&gt;
&lt;br /&gt;
==== RHEL6/CentOS6 ====&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to &amp;lt;tt&amp;gt;/etc/yum.repos.d/ox.repo&amp;lt;/tt&amp;gt;. Replace VERSION with the version you are using (e.g. 7.4.2, 7.6.0). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 [ox-updates-appsuiteui]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/RHEL6/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
 &lt;br /&gt;
 [ox-updates-backend]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/RHEL6/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
&lt;br /&gt;
 $ yum upgrade&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
==== RHEL7/CentOS7 ====&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to &amp;lt;tt&amp;gt;/etc/yum.repos.d/ox.repo&amp;lt;/tt&amp;gt;. Replace VERSION with the version you are using (e.g. 7.4.2, 7.6.0). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 [ox-updates-appsuiteui]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/RHEL7/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
 &lt;br /&gt;
 [ox-updates-backend]&lt;br /&gt;
 name=Open-Xchange Updates&lt;br /&gt;
 baseurl=http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/RHEL7/&lt;br /&gt;
 gpgkey=http://software.open-xchange.com/oxbuildkey.pub&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 metadata_expire=0m&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ yum update&lt;br /&gt;
&lt;br /&gt;
 $ yum upgrade&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ /etc/init.d/open-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind)&lt;br /&gt;
&lt;br /&gt;
==== SLES 11 ====&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to the repository list. Replace VERSION with the version you are using (e.g. 7.4.2, 7.6.0). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/SLES11/ OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/SLES11/ OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ zypper dup -r OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper dup -r OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
You might need to run&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
&lt;br /&gt;
to update the repository metadata before running ''zypper up''.&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ rcopen-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind.&lt;br /&gt;
&lt;br /&gt;
==== SLES 12 ====&lt;br /&gt;
&lt;br /&gt;
If you want to update an older version of Open-Xchange App Suite to the latest maintenance release, add the following entry to the repository list. Replace VERSION with the version you are using (e.g. 7.4.2, 7.6.0). See [[AppSuite:Version_Support_Committment]] for the currently supported versions. Also, make sure that your repository configuration points at the versioned base installation repositories (instead of using the &amp;lt;tt&amp;gt;stable&amp;lt;/tt&amp;gt; symlink.)&lt;br /&gt;
&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/appsuiteui/updates/SLE_12/ OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper ar http://CUSTOMERID:PASSWORD@software.open-xchange.com/products/appsuite/VERSION/backend/updates/SLE_12/ OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
&lt;br /&gt;
 $ zypper dup -r OXAPPSUITEUIUPDATES&lt;br /&gt;
 $ zypper dup -r OXBACKENDUPDATES&lt;br /&gt;
&lt;br /&gt;
You might need to run&lt;br /&gt;
&lt;br /&gt;
 $ zypper ref&lt;br /&gt;
&lt;br /&gt;
to update the repository metadata before running ''zypper up''.&lt;br /&gt;
&lt;br /&gt;
After the new packages are installed, the open-xchange process needs a restart:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt;$ rcopen-xchange restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Please, keep the [[#Warnings|warning about database updates]] in mind.&lt;br /&gt;
&lt;br /&gt;
= Updating UI plugins =&lt;br /&gt;
&lt;br /&gt;
If you update only UI plugins without simultaneously upgrading the core UI packages to a new version, you need to perform an additional step after the update to make the changes visible to users.&lt;br /&gt;
&lt;br /&gt;
The package &amp;lt;tt&amp;gt;open-xchange-appsuite&amp;lt;/tt&amp;gt; contains a timestamp which is different in each version. The JavaScript UI in every user's browser will reload all cached code and data whenever this value changes. Since this value does not change when updating only plugin packages, the value must be changed manually with the following command:&lt;br /&gt;
&lt;br /&gt;
 $ /opt/open-xchange/sbin/touch-appsuite --timestamp=20170101.123400&lt;br /&gt;
&lt;br /&gt;
If you only have one OX node, the parameter &amp;lt;code&amp;gt;--timestamp&amp;lt;/code&amp;gt; can be omitted. It defaults to the current UTC time anyway.&lt;br /&gt;
&lt;br /&gt;
When updating a cluster, the command must use the same timestamp value on every node. Otherwise, browsers will clear their cache and re-download the entire UI code every time load balancer sends them to a different node (i.e. on almost every login). This is also why the timestamps can't be updated automatically: a node doesn't know which value other nodes will pick, which of them are part of the same update, etc.&lt;br /&gt;
&lt;br /&gt;
The quickest way to obtain a value for the timestamp parameter is to run the command with the parameter &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt;. It will then print a help message with the current time as an example. For automation, you can use the output of&lt;br /&gt;
&lt;br /&gt;
 date -u +%Y%m%d.%H%M%S&lt;br /&gt;
&lt;br /&gt;
Again: this value must be computed once, and then the same value must be used on every node in the cluster.&lt;br /&gt;
&lt;br /&gt;
This step can be performed on each node separately after each node has been updated, or on all nodes at once after all nodes have been updated. If Apache has its own set of dedicated nodes, the &amp;lt;tt&amp;gt;touch-appsuite&amp;lt;/tt&amp;gt; call must be performed on the web server nodes, after all corresponding &amp;lt;tt&amp;gt;&amp;lt;plugin&amp;gt;-static&amp;lt;/tt&amp;gt; packages have been updated.&lt;br /&gt;
&lt;br /&gt;
[[Category: OX7]]&lt;br /&gt;
[[Category: AppSuite]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Administrator]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=Contact-Support&amp;diff=24207</id>
		<title>Contact-Support</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=Contact-Support&amp;diff=24207"/>
		<updated>2018-08-01T04:48:55Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= How to contact the Open-Xchange Support? =&lt;br /&gt;
&lt;br /&gt;
= Concern: =&lt;br /&gt;
You are entitled for Advanced Support and have obtained one of Open-Xchange's Support offerings, have registered all your Support Keys, which you have got after purchasing your Support offering according the information provided in the [http://knowledgebase.open-xchange.com/support/self-service/registration.html My Registrations] section.&lt;br /&gt;
&lt;br /&gt;
Furthermore you have an issue with your Open-Xchange Software and need help by the Open-Xchange Support.&lt;br /&gt;
&lt;br /&gt;
= Todo: =&lt;br /&gt;
Send an E-Mail to &amp;lt;support AT open-xchange.com&amp;gt; and provide the following information within the E-Mail body. Please take care to put your Support Key always to the top. If you provide more than one key the first recognised key wins.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: We can only guarantee fast responses in case you report your incident or problem in English.&lt;br /&gt;
&lt;br /&gt;
 Support Key: OX-SUPPORT-OR-LICENSE-KEY-XXX&lt;br /&gt;
 Server: url of the machine&lt;br /&gt;
 Server Version: server version or package list&lt;br /&gt;
 Platform: Please choose one from [https://oxpedia.org/wiki/index.php?title=Contact-Support:PossibleValues#Platform: possible values].&lt;br /&gt;
 GUI Version: GUI version or package list&lt;br /&gt;
 Category: Please choose one from [https://oxpedia.org/wiki/index.php?title=Contact-Support:PossibleValues#Category: possible values].&lt;br /&gt;
 Severity: 4, 3, 2, 1 (see description of Severity Levels)&lt;br /&gt;
 Track-ID: the customer's internal tracking number, e.g. from its Bugzilla&lt;br /&gt;
 Product: Please choose one from [https://oxpedia.org/wiki/index.php?title=Contact-Support:PossibleValues#Product: possible values].&lt;br /&gt;
 &lt;br /&gt;
 Steps to reproduce:&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 Current behaviour:&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 Expected behaviour:&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
The Severity of an Incident determines the impact it has on the customer's business and therefore the urgency of solving an Incident of certain impact.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' Please note that Open-Xchange's response time depends on both the Severity and the Service Level Agreement between the customer and Open-Xchange.&lt;br /&gt;
&lt;br /&gt;
If all of the above information has been provided a confirmation mail is sent from Open-Xchange's ticket system which includes the ticket number for that incident.&lt;br /&gt;
&lt;br /&gt;
= Open-Xchange Severity: =&lt;br /&gt;
&lt;br /&gt;
== Severity 1==&lt;br /&gt;
&lt;br /&gt;
Shall mean Incidents that are defined as a complete outage and do not allow the Licensee to further conduct his business. Licensee's system or application is completely not available and no Workaround exists. The Incident affects all users deployed on the Joint Solution Environment.&lt;br /&gt;
Also means a security or general threat causing potential risk to the customers’ data integrity or privacy.&lt;br /&gt;
A situation in which one or several servers do not operate correctly is not a Severity 1 issue, unless the issue causes one of the above to happen.&lt;br /&gt;
&lt;br /&gt;
==Severity 2==&lt;br /&gt;
&lt;br /&gt;
The Licensee’s operation is severely disrupted. A business critical component of the Joint Solution Environment cannot be used by a majority of the users.&lt;br /&gt;
&lt;br /&gt;
==Severity 3==&lt;br /&gt;
&lt;br /&gt;
Shall mean Incidents which involve partial loss of non-critical functionality, one which impairs many operations, but allows the Licensee to continue to operate.&lt;br /&gt;
&lt;br /&gt;
==Severity 4==&lt;br /&gt;
&lt;br /&gt;
Shall mean general usage questions, recommendations for product enhancements or modifications, and calls that are passed to the Parties for informational purposes. This includes but is not limited to documentation and translation errors.&lt;br /&gt;
&lt;br /&gt;
= Personal Data Policy =&lt;br /&gt;
According to German law, companies are forced to handle any (log) files from customers which contain data related to a third person or has any personal protection in a special way. Personal data shall mean any information concerning the personal or material circumstances of an identified or identifiable natural person. Even so they have to be deleted once they aren't used any more. To fulfil this requirement, customers and support agents have to keep the readable ticket communication, in form of email/article body, subject or attachment names, free from any personal data. This can be every thing from names, email addresses, screen-shots, logs files and even credentials to system accounts. This personal data only has to be handed over in form of attachments which was common practice before. Transfer channels for personal data are attachments via the ticket system, attachment in encrypted emails or provided by protected download links. How to send encrypted emails via PGP is described [http://sdb.open-xchange.com/node/59 here].&lt;br /&gt;
&lt;br /&gt;
The integrity of an 'Incident Request' with all available data needs to be saved up to 90 days after a ticket was closed to ensure a holistic assessment in case of Contractual complaints. This time frame is mandatory and gives also the customer time for detailed tests. In case of reopening an incident within these three months all information is still available and needs not to be recollected by customers and end users.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange introduced a weekly deletion process, the deletion work on ticket attachments and on raw email files which are affected by attachments. The automatic deletion of all ticket attachments takes place weekly at Sunday and affects all tickets which are in a 'closed' state since 90 days.&lt;br /&gt;
&lt;br /&gt;
= Creating an OX Support Tarball =&lt;br /&gt;
&lt;br /&gt;
[http://oxpedia.org/wiki/index.php?title=AppSuite:Oxsysreport Creating an OX Support Tarball]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=Kontakt-Zu-Support&amp;diff=24206</id>
		<title>Kontakt-Zu-Support</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=Kontakt-Zu-Support&amp;diff=24206"/>
		<updated>2018-08-01T04:48:48Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Open-Xchange Support kontaktieren =&lt;br /&gt;
&lt;br /&gt;
= Anliegen: =&lt;br /&gt;
Sie sind im Besitz eines erweiterten Support Vertrags mit Open-Xchange, Sie haben Ihren Support Key, wie unter [http://knowledgebase.open-xchange.com/support/self-service/registration.html Meine Registrierungen] beschrieben freigeschaltet und benötigen nun Unterstützung bei der Lösung eines Problems mit Ihrem Open-Xchange Produkt.&lt;br /&gt;
&lt;br /&gt;
= Vorgehen: =&lt;br /&gt;
Senden Sie eine E-Mail an &amp;lt;support AT open-xchange.com&amp;gt; und fügen Sie folgende Informationen dem &amp;quot;Mail Body&amp;quot; bei. Bitte achten Sie darauf, den Support Key immer an oberster Stelle anzugeben. Sollten mehrere Keys in der Mail erkannt werden, so gewinnt der zuerst erkannte:&lt;br /&gt;
&lt;br /&gt;
WICHTIG: Wir können schnelle Antworten nur garantieren, wenn Sie ihre Störungen und Probleme in englisch melden.&lt;br /&gt;
&lt;br /&gt;
 Support Key: OX-SUPPORT-ODER-LIZENZ-KEY-XXX&lt;br /&gt;
 Server: URL des Servers&lt;br /&gt;
 Server Version: Server Version oder Paket Liste&lt;br /&gt;
 Platform: Bitte wählen Sie einen Eintrag aus den [https://oxpedia.org/wiki/index.php?title=Contact-Support:PossibleValues#Platform: möglichen Werten].&lt;br /&gt;
 GUI Version: GUI Version oder Paket Liste&lt;br /&gt;
 Category: Bitte wählen Sie einen Eintrag aus den [https://oxpedia.org/wiki/index.php?title=Contact-Support:PossibleValues#Module: möglichen Werten].&lt;br /&gt;
 Severity: 4, 3, 2, 1 (siehe auch Beschreibung der Severity Level)&lt;br /&gt;
 Track-ID: Kunden interne Nachverfolgungsreferenz, z.B. dessen Bugzilla&lt;br /&gt;
 Product: Bitte wählen Sie einen Eintrag aus den [https://oxpedia.org/wiki/index.php?title=Contact-Support:PossibleValues#Product: möglichen Werten].&lt;br /&gt;
 &lt;br /&gt;
 Steps to reproduce:&lt;br /&gt;
 ...&lt;br /&gt;
 Current behaviour:&lt;br /&gt;
 ...&lt;br /&gt;
 Expected behaviour:&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Die Severity (Schwere) einer Anfrage beschreibt den Einfluss einer Störung auf den Geschäftsablauf eines Kunden und somit die Dringlichkeit der Beseitigung einer möglichen Störung.&lt;br /&gt;
&lt;br /&gt;
'''Wichtig:''' Die Reaktionszeit von Open-Xchange hängt sowohl von der gewählten Severity der Anfrage als auch von einem &amp;quot;Service Level Agreement&amp;quot; (SLA) zwischen dem Kunden und Open-Xchange ab.&lt;br /&gt;
&lt;br /&gt;
Sobald alle obigen Informationen in der Anfrage enthalten sind, wird eine Bestätigungs E-Mail von dem Open-Xchange Ticketsystem verschickt, welche die Ticketnummer für die weitere Kommunikation enthält.&lt;br /&gt;
&lt;br /&gt;
= Open-Xchange Severity (English only) =&lt;br /&gt;
&lt;br /&gt;
== Severity 1==&lt;br /&gt;
&lt;br /&gt;
Shall mean Incidents that are defined as a complete outage and do not allow the Licensee to further conduct his business. Licensee's system or application is completely not available and no Workaround exists. The Incident affects all users deployed on the Joint Solution Environment.&lt;br /&gt;
Also means a security or general threat causing potential risk to the customers’ data integrity or privacy.&lt;br /&gt;
A situation in which one or several servers do not operate correctly is not a Severity 1 issue, unless the issue causes one of the above to happen.&lt;br /&gt;
&lt;br /&gt;
==Severity 2==&lt;br /&gt;
&lt;br /&gt;
The Licensee’s operation is severely disrupted. A business critical component of the Joint Solution Environment cannot be used by a majority of the users.&lt;br /&gt;
&lt;br /&gt;
==Severity 3==&lt;br /&gt;
&lt;br /&gt;
Shall mean Incidents which involve partial loss of non-critical functionality, one which impairs many operations, but allows the Licensee to continue to operate.&lt;br /&gt;
&lt;br /&gt;
==Severity 4==&lt;br /&gt;
&lt;br /&gt;
Shall mean general usage questions, recommendations for product enhancements or modifications, and calls that are passed to the Parties for informational purposes. This includes but is not limited to documentation and translation errors.&lt;br /&gt;
&lt;br /&gt;
= Personal Data Policy (English only) =&lt;br /&gt;
According to German law, companies are forced to handle any (log) files from customers which contain data related to a third person or has any personal protection in a special way. Personal data shall mean any information concerning the personal or material circumstances of an identified or identifiable natural person. Even so they have to be deleted once they aren't used any more. To fulfil this requirement, customers and support agents have to keep the readable ticket communication, in form of email/article body, subject or attachment names, free from any personal data. This can be every thing from names, email addresses, screen-shots, logs files and even credentials to system accounts. This personal data only has to be handed over in form of attachments which was common practice before. Transfer channels for personal data are attachments via the ticket system, attachment in encrypted emails or provided by protected download links. How to send encrypted emails via PGP is described [http://sdb.open-xchange.com/node/59 here].&lt;br /&gt;
&lt;br /&gt;
The integrity of an 'Incident Request' with all available data needs to be saved up to 90 days after a ticket was closed to ensure a holistic assessment in case of Contractual complaints. This time frame is mandatory and gives also the customer time for detailed tests. In case of reopening an incident within these three months all information is still available and needs not to be recollected by customers and end users.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange introduced a weekly deletion process, the deletion work on ticket attachments and on raw email files which are affected by attachments. The automatic deletion of all ticket attachments takes place weekly at Sunday and affects all tickets which are in a 'closed' state since 90 days.&lt;br /&gt;
&lt;br /&gt;
= Erstellung eines OX Support Tarball =&lt;br /&gt;
&lt;br /&gt;
[http://oxpedia.org/wiki/index.php?title=AppSuite:Oxsysreport Erstellung eines OX Support Tarball]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:OX_System_Requirements&amp;diff=24176</id>
		<title>AppSuite:OX System Requirements</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:OX_System_Requirements&amp;diff=24176"/>
		<updated>2018-07-18T11:26:34Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Object Storages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= OX App Suite Requirements - Open-Xchange supported components overview =&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview about the supported components at the OX User Front-End, Connector for Microsoft Outlook and Connector for Business Mobility. This overview makes no claim to be complete.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange Server 6 overview tables about the supported components at the OX User Front-End, Connector for Microsoft Outlook and Connector for Business Mobility are available at [[OX_System_Requirements|OX 6 Requirements - Open-Xchange supported components overview]]&lt;br /&gt;
&lt;br /&gt;
Information about Maintenance expiries of components, versions and browser support, can be found in the [[AppSuite:Versioning_and_Numbering#Maintenance_expires|Maintenance Expires Table]]&lt;br /&gt;
&lt;br /&gt;
== Hardware Requirements ==&lt;br /&gt;
=== General Assumptions ===&lt;br /&gt;
Open-Xchange App Suite Server (middleware services) is designed to run on physical servers or virtual machines of the same flavor. Cloud environments might be used in terms of Infrastructure as a Service (IaaS), meaning that all components need to be deployed in a classical manner on virtual machines.&lt;br /&gt;
&lt;br /&gt;
This means in particular, but not only:&lt;br /&gt;
&lt;br /&gt;
* Infrastructure is &amp;quot;quasi-static&amp;quot;. We don't need to take into account things like VMs coming and going dynamically, dynamic IPs, volatile (&amp;quot;ephemeral&amp;quot;) data&lt;br /&gt;
* &amp;quot;Database as a service&amp;quot; is not allowed. This typically is a highly customized &amp;quot;MySQL like&amp;quot; storage engine, and not a true MySQL, and we can't control flavor, version, setup, etc. If need for configuration changes is identified, we won't be able to change anything.&lt;br /&gt;
&lt;br /&gt;
So to summarize: we expect any virtualized platform to behave and work just like a well-known non-virtualized / physical platform.&lt;br /&gt;
&lt;br /&gt;
Especially we expect the virtual hardware to be not over-provisioned. Each VM must have dedicated resources with respect to CPU cores, RAM, IOPS, storage, network bandwidth, network latency, etc.&lt;br /&gt;
&lt;br /&gt;
Network is expected to be flat, inside one datacenter, no multi-datacenter, no segments. No packet loss, low latency.&lt;br /&gt;
&lt;br /&gt;
'''Disclaimer: All recommendations below are without guarantee and can differ for specific deployments. For mid- and large-scale setups a detailed deployment planning and sizing tests are mandatory and should be agreed on with OX Professional Services.'''&lt;br /&gt;
&lt;br /&gt;
=== High Level Design / OS setup ===&lt;br /&gt;
Operate services separately (USM, Document/Image Converters) as described in Cluster Setup.&lt;br /&gt;
&lt;br /&gt;
Clocks between all nodes must be synchronized (e.g. via NTP).&lt;br /&gt;
&lt;br /&gt;
Open file/max process limits need to be adjusted properly. Based on the used Linux distribution and init system configuration will differ, see Resource Limits for further explanation.&lt;br /&gt;
&lt;br /&gt;
Platform Architecture: 64 bit versions (x84_64) of the supported [[#Software Requirements | Linux distributions]]&lt;br /&gt;
&lt;br /&gt;
=== Node Sizing ===&lt;br /&gt;
* Max. 8 GB heap per JVM + 4 GB system memory for other daemons and the OS (buffers, caches)&lt;br /&gt;
* 4 CPU cores (virtual, physical or hyperthreads)&lt;br /&gt;
* Disk space&lt;br /&gt;
** 5 GB for OS and software&lt;br /&gt;
** &amp;lt;code&amp;gt;2 * system memory&amp;lt;/code&amp;gt; of free disk space (i.e. 12 GB RAM =&amp;gt; 24 GB free disk space) for file spooling, log files, heap and core dumps&lt;br /&gt;
&lt;br /&gt;
=== Untested/Unsupported Deployments ===&lt;br /&gt;
* Changes to Garbage Collector settings&lt;br /&gt;
* Running in containerized environments (Docker, rkt)&lt;br /&gt;
* Elasticity/High velocity of nodes going up and down: Services are sometimes stateful and demand static configuration&lt;br /&gt;
* Cloud platform services (PaaS) like database systems (for example AWS RDS)&lt;br /&gt;
* Multi-site active-active&lt;br /&gt;
&lt;br /&gt;
== Software Requirements ==&lt;br /&gt;
&lt;br /&gt;
=== Linux Distributions ===&lt;br /&gt;
&lt;br /&gt;
OX App Suite is available as Linux packages for the following distributions:&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
 |'''Distribution'''&lt;br /&gt;
 |'''Versions'''&lt;br /&gt;
 |'''Derivates'''&lt;br /&gt;
|- &lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
 |Suse Linux Enterprise Server&lt;br /&gt;
 |12&lt;br /&gt;
 |None&lt;br /&gt;
|-&lt;br /&gt;
 |Red Hat Enterprise Linux&lt;br /&gt;
 |6,7&lt;br /&gt;
 |CentOS&lt;br /&gt;
|-&lt;br /&gt;
 |Debian&lt;br /&gt;
 |8 (Jessie), 9 (stretch)&lt;br /&gt;
 |None&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
OX App Suite Middleware requires OpenJDK headless JRE 8 or 9.&lt;br /&gt;
&lt;br /&gt;
'''Please note:''' For Debian 8 (Jessie) OpenJDK 8 is only available via the [https://packages.debian.org/search?keywords=jessie-backports jessie-backports] repository.&lt;br /&gt;
&lt;br /&gt;
=== Databases ===&lt;br /&gt;
&lt;br /&gt;
OX App Suite uses MySQL with the InnoDB storage engine as its primary data store. The following vendors and products are supported.&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
 |'''Vendor'''&lt;br /&gt;
 |'''Product'''&lt;br /&gt;
 |'''Versions'''&lt;br /&gt;
|- &lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
 |Oracle&lt;br /&gt;
 |MySQL Community Edition, Standard Edition, Enterprise Edition&lt;br /&gt;
 |[5.6.x, 5.7.x]&lt;br /&gt;
|-&lt;br /&gt;
 |MariaDB&lt;br /&gt;
 |MariaDB Server, Galera Cluster&lt;br /&gt;
 |[10.1.x, 10.2.x]&lt;br /&gt;
|-&lt;br /&gt;
 |Percona&lt;br /&gt;
 |XtraDB Cluster&lt;br /&gt;
 |[5.6.x, 5.7.x]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Important Notes ===&lt;br /&gt;
&lt;br /&gt;
* For some Linux distributions the included MySQL/MariaDB packages are too old to be used with App Suite. It is mandatory then to install a supported version from upstream package sources. Possible sources are the official vendor repositories of MySQL, MariaDB or Percona as well as for example Red Hat Software Collections.&lt;br /&gt;
* Required MySQL configuration differs between App Suite 7.8.4 and 7.10.0 and also between the different database systems in terms of SQL modes. See [[My.cnf]] for details.&lt;br /&gt;
* For upgrades to App Suite 7.10.0 a comprehensive database upgrade guide exists: [[AppSuite:7_10_Database_Migration]]&lt;br /&gt;
&lt;br /&gt;
== File Storage ==&lt;br /&gt;
&lt;br /&gt;
=== Temporary Data ===&lt;br /&gt;
&lt;br /&gt;
OX App Suite stores temporary files in the local file system, e.g. for spooling of uploaded data. Any file system supported by the installed JRE is suitable.&lt;br /&gt;
&lt;br /&gt;
=== Persistent Data ===&lt;br /&gt;
&lt;br /&gt;
Persistent data like OX Drive files, PIM attachments etc. needs to be stored in a distributed file system that is available from all server nodes. For single-node setups a local file system mount point can be used, small to mid-scale setups can be powered by NFS. For large-scale setups object storages should be considered.&lt;br /&gt;
&lt;br /&gt;
==== Object Storages ====&lt;br /&gt;
&lt;br /&gt;
OX App Suite ships with different optional adapters to support object storages.&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
 |'''Vendor'''&lt;br /&gt;
 |'''Product'''&lt;br /&gt;
 |'''API'''&lt;br /&gt;
 |'''Remarks'''&lt;br /&gt;
|- &lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
 |Amazon&lt;br /&gt;
 |AWS S3&lt;br /&gt;
 |S3 HTTP API&lt;br /&gt;
 |See also [[AppSuite:S3_File_Store]]&lt;br /&gt;
|-&lt;br /&gt;
 |CEPH&lt;br /&gt;
 |RadosGW&lt;br /&gt;
 |S3 HTTP API&lt;br /&gt;
 |See also [[AppSuite:S3_File_Store]]&lt;br /&gt;
|-&lt;br /&gt;
 |Scality&lt;br /&gt;
 |Scality RING&lt;br /&gt;
 |Sproxyd HTTP API&lt;br /&gt;
 |See also [[AppSuite:Scality_File_Store]]&lt;br /&gt;
|-&lt;br /&gt;
 |OpenStack&lt;br /&gt;
 |Swift&lt;br /&gt;
 |Object Storage API V1&lt;br /&gt;
 |Support for Swift is experimental and could be removed again in the future. See also [[AppSuite:Swift_File_Store]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Desktop Browser (Minimum display resolution: 1024 x 768)==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Browser'''&lt;br /&gt;
  |'''OX App Suite User Front-End'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Microsoft Internet Explorer 10/11&lt;br /&gt;
  |v7.6.3&lt;br /&gt;
|-&lt;br /&gt;
  |Microsoft Internet Explorer 11/Edge&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Mozilla Firefox (latest &amp;amp; previous version)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Google Chrome (latest &amp;amp; previous version)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Apple Safari (10.01 &amp;amp; 10.03; Mac OS X only)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Mobile Device Support==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Mobile Device'''&lt;br /&gt;
  |'''Supported Browser'''&lt;br /&gt;
  |'''OX App Suite User Front-End'''&lt;br /&gt;
  |'''Minimum Speed Requirements'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |iPhone on iOS 10 / iOS 11&lt;br /&gt;
  |Safari&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
  |3G connections (512/256kBit/s, 350ms latency)&lt;br /&gt;
 |-&lt;br /&gt;
  |Smartphone on Android 4.1 or later&lt;br /&gt;
  |Chrome (latest &amp;amp; previous version)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
  |3G connections (512/256kBit/s, 350ms latency)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tablet Support==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Tablet'''&lt;br /&gt;
  |'''Supported Browser'''&lt;br /&gt;
  |'''OX App Suite User Front-End'''&lt;br /&gt;
  |'''Minimum Speed Requirements'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Apple iPad (all devices) on iOS 10 / iOS 11&lt;br /&gt;
  |Safari&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
  |3G connections (512/256kBit/s, 350ms latency)&lt;br /&gt;
 |-&lt;br /&gt;
  |Tablets on Android 4.1 or later&lt;br /&gt;
  |Chrome (latest &amp;amp; previous version)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
  |3G connections (512/256kBit/s, 350ms latency)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Calendar/Contact synchronization Apple Mac OS X ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |Calendar synchronization with CalDAV&lt;br /&gt;
  |Contacts synchronization with CardDAV&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
  |Mac OS X 10.11 (El Capitan)&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
|-&lt;br /&gt;
  |macOS 10.12, 10.13 (Sierra &amp;amp; High Sierra)&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Calendar/Contact synchronization Apple iOS ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |Calendar synchronization with CalDAV&lt;br /&gt;
  |Contacts synchronization with CardDAV&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
  |Apple iOS 10 / iOS 11&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Mobility Solution - Supported-  Platforms, Features and Devices ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Feature/Technology/Device'''&lt;br /&gt;
  |[http://oxpedia.org/wiki/index.php?title=OXtender_for_Business_Mobility '''OXtender for Business Mobility'''] (availalble for App Suite, OXHE, OXSE)&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Exchange Active Sync 2.5&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |-&lt;br /&gt;
  |Exchange Active Sync 12.1&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Access and creation of emails&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
|-&lt;br /&gt;
  |Personal PIM folder&lt;br /&gt;
  |[[File:check.gif]] &lt;br /&gt;
|-&lt;br /&gt;
  |Public and Shared PIM folder&lt;br /&gt;
  |[[File:cross.gif]]&lt;br /&gt;
|-&lt;br /&gt;
  |Global address book&lt;br /&gt;
  |[[File:check.gif]] &lt;br /&gt;
|-&lt;br /&gt;
  |Push E-Mail&lt;br /&gt;
  |[[File:check.gif]] &lt;br /&gt;
|-&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Windows Phone 8 (latest &amp;amp; previous minor versions), Windows Phone 10 (latest &amp;amp; previous minor versions)&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |-&lt;br /&gt;
  |Apple iOS 10 / iOS 11&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |-&lt;br /&gt;
  |Android 4.1 or later&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Drive for Clients ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX App Suite v7.8.4, OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Drive for Windows&lt;br /&gt;
  |Latest versions of Windows 8, latest versions of Windows 10 (no support of Mac OS X clients with emulators and Windows RT)&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Drive for Mac OS&lt;br /&gt;
  |Mac OS X 10.11 (El Capitan), macOS 10.12, 10.13 (Sierra &amp;amp; High Sierra)&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Drive for iOS&lt;br /&gt;
  |Apple iOS 10, Apple iOS 11&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Drive for Android&lt;br /&gt;
  |Smartphone on Android 4.1 or later with Chrome (latest &amp;amp; previous version), Tablets on Android 4.1 or later with Chrome (latest &amp;amp; previous version)&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Mail App ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform / User Interface'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX App Suite v7.8.4, OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Mail for iOS&lt;br /&gt;
  |Apple iOS 10, Apple iOS 11&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Mail for Android&lt;br /&gt;
  |Smartphone on Android 4.3 or later&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Mail App v2 ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform / User Interface'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |[http://oxpedia.org/wiki/index.php?title=AppSuite:Main_Page_Quickinstall#Quick_Installation_Guide OX App Suite]&lt;br /&gt;
  |OX App Suite v7.8.4 or later&lt;br /&gt;
 |-&lt;br /&gt;
  |[http://oxpedia.org/wiki/index.php?title=AppSuite:Mobile_API_Facade Mobile API Facade]&lt;br /&gt;
  |Mobile API Facade v1.0.2 or later (until OX App Suite v7.8.4)&amp;lt;br&amp;gt;Mobile API Facade v1.2.0 or later (from OX App Suite v7.10.0)&lt;br /&gt;
 |-&lt;br /&gt;
  |Push Notification Package&lt;br /&gt;
  |Package &amp;quot;open-xchange-mobile-api-facade-push-certificates&amp;quot; (available to App Suite licensees only)&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Mail App v2.0 for iOS&lt;br /&gt;
  |Apple iOS 9.3, iOS 10, iOS 11 &amp;lt;br&amp;gt;Server reachable via TLS 1.2&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Mail App v2.0 for Android&lt;br /&gt;
  |Android 5.0 (Lollipop) or higher&amp;lt;br&amp;gt;Server reachable via TLS 1.2&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Sync App ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform / User Interface'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX App Suite v7.8.4, OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Sync App for Android&lt;br /&gt;
  |Smartphone on Android 4.0 or later&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Guard ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform / User Interface'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX Guard since v2.6.0: OX App Suite v7.8.3&amp;lt;br&amp;gt;OX Guard since v2.8.0: OX App Suite v7.8.4&amp;lt;br&amp;gt;OX Guard since v2.10.0: OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Mobile Device and Tablet Support&lt;br /&gt;
  |Apple iPhone on iOS 10 / iOS 11: Safari (latest version &amp;amp; previous version)&amp;lt;br&amp;gt;Smartphone on Android 4.1 or later: Chrome (latest &amp;amp; previous version)&amp;lt;br&amp;gt;Apple iPad (all devices) on iOS 10 / iOS 11: Safari Safari (latest version &amp;amp; previous version)&amp;lt;br&amp;gt;Tablets on Android 4.1 or later: Chrome (latest &amp;amp; previous version)&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== eM Client for OX App Suite ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |[http://oxpedia.org/wiki/index.php?title=AppSuite:EM_Client_for_OX_App_Suite '''eM Client for OX App Suite''']&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX App Suite v7.8.4, OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Client PC operating system&lt;br /&gt;
  |Latest versions of Windows 8 (no support of start screen tiles), latest versions of Windows 10 (no support of Mac OS X clients with emulators and Windows RT)&lt;br /&gt;
  |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: OX7]]&lt;br /&gt;
[[Category: AppSuite]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:7_10_Database_Migration&amp;diff=24175</id>
		<title>AppSuite:7 10 Database Migration</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:7_10_Database_Migration&amp;diff=24175"/>
		<updated>2018-07-18T11:14:24Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Database System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.10.0}}&lt;br /&gt;
&lt;br /&gt;
= Database Migration with OX App Suite v7.10.0 =&lt;br /&gt;
&lt;br /&gt;
OX App Suite v7.10.0 introduces significant changes regarding the underlying MySQL database system that require special attention in case of upgrades from former versions. Please read this paper carefully to ensure a smooth and clean upgrade process.&lt;br /&gt;
&lt;br /&gt;
== Change Overview ==&lt;br /&gt;
&lt;br /&gt;
The most significant changes are:&lt;br /&gt;
* New version and configuration requirements.&lt;br /&gt;
* Most VARCHAR columns need to be migrated to utf8mb4 character encoding.&lt;br /&gt;
* A major rewrite of the calendar application requires full data migration.&lt;br /&gt;
&lt;br /&gt;
We strongly recommend to thoroughly plan and test the upgrade procedure. To gain insights about update task runtimes and the expected load, our recommendation is to clone ConfigDB and the biggest UserDB and perform an isolated test upgrade that especially covers the calendar migration and character encoding changes. Update task durations can be significantly longer than with previous upgrades and the migrations might cause noticeable higher I/O load. Also some additional disk space is needed during and after the migrations.&lt;br /&gt;
&lt;br /&gt;
== Database System ==&lt;br /&gt;
&lt;br /&gt;
MySQL Server is supported in versions 5.6 and 5.7 with recent patch levels only and MariaDB Server 10.1 and 10.2 respectively. Support for 5.6/10.1 exists for compatibility reasons and is transitional. We recommend upgrading to 5.7/10.2 as soon as possible. Any database system upgrade must happen before App Suite is upgraded to OX App Suite v7.10.0. Please follow the respective guides of your database vendor carefully.&lt;br /&gt;
&lt;br /&gt;
Different App Suite and database system versions require different configurations of the DBMS, please follow [[My.cnf]] to have your database configured in a sane way. Especially the following items require some attention with the upgrade to App Suite 7.10.0 and upgrades of the DBMS itself:&lt;br /&gt;
&lt;br /&gt;
* Supported SQL modes are only &amp;lt;code&amp;gt;NO_ENGINE_SUBSTITUTION&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;NO_AUTO_CREATE_USER&amp;lt;/code&amp;gt;. Starting with App Suite 7.10.0, &amp;lt;code&amp;gt;ONLY_FULL_GROUP_BY&amp;lt;/code&amp;gt; is also supported for MySQL 5.7. It is still not with older versions of MySQL or any MariaDB version! To review the current value, use &amp;lt;code&amp;gt;SHOW GLOBAL VARIABLES WHERE Variable_name = 'sql_mode';&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Ensure that &amp;lt;code&amp;gt;character_set_server&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;utf8&amp;lt;/code&amp;gt; for App Suite 7.8.x. Again the current global default value can be obtained via &amp;lt;code&amp;gt;SHOW GLOBAL VARIABLES WHERE Variable_name = 'character_set_server';&amp;lt;/code&amp;gt;. With 7.10.0 being fully rolled out, this setting must then be changed to &amp;lt;code&amp;gt;utf8mb4&amp;lt;/code&amp;gt;. If &amp;lt;code&amp;gt;collation_server&amp;lt;/code&amp;gt; is configured explicitly, it must be set to a matching value according to the character set in either case!&lt;br /&gt;
&lt;br /&gt;
Note that App Suite &amp;lt;= 7.8.4 did not support MySQL 5.7/MariaDB 10.2 so far. While we recommend it for 7.10.0, this leaves a lack of definition during the upgrade process. We consider running 7.8.4 on top of MySQL 5.7/MariaDB 10.2 a valid scenario as long as it is transitional during the upgrade phase. Please take our configuration recommendations seriously to mitigate potential user-facing issues as far as possible.&lt;br /&gt;
&lt;br /&gt;
== Upgrade Procedure ==&lt;br /&gt;
&lt;br /&gt;
The upgrade to OX App Suite v7.10.0 can be performed like any other major upgrade before. However, the duration of blocking database update tasks for the mentioned charset and calendar migrations could conflict with customers’ availability demands. Therefore it is possible to decouple these special time- and resource-intensive tasks from the plain version upgrade. In this section a multi-step approach is described that performs the version upgrade before and independently from the migrations. Every step always results in a working system that is ready to serve user traffic. Some functional implications that affect user experience are outlined in the according subsections.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' Even though the first step leads to a basically working OX App Suite v7.10.0 environment, the subsequent steps are not optional but mandatory! Skipping the migrations will leave a few calendar features dysfunctional and can lead to issues with certain SQL queries that use explicit collations for searching and sorting. Running OX App Suite v7.10.0 in production without having all parts of the migration fulfilled is not supported – OX support will request you to complete the migration tasks when reporting issues that are not related to the migration itself. &lt;br /&gt;
&lt;br /&gt;
== Initial OX App Suite v7.10.0 Rollout ==&lt;br /&gt;
If not done so far, upgrade your MySQL installation to a version supported with OX App Suite v7.10.0 but configure it to be compatible with OX App Suite v7.8.x as described in the “Database System” section.&lt;br /&gt;
&lt;br /&gt;
Despite the fact that the two special migrations for calendar and character sets are explicitly skipped, this section assumes that the “Rolling Upgrade with breaking Hazelcast upgrade” is applied as described in [[AppSuite:Running_a_cluster#Updating_a_Cluster]]. For the application server upgrade, the common guide from [[AppSuite:UpdatingOXPackages]] can be followed.&lt;br /&gt;
&lt;br /&gt;
Prepare a dedicated App Suite middleware node that will be used to perform the database update tasks. The node must not be serving any user traffic and be prepared with&lt;br /&gt;
&lt;br /&gt;
* OX App Suite v7.10.0 packages&lt;br /&gt;
* Configuration according to the user production nodes&lt;br /&gt;
* The Hazelcast rolling upgrade compatibility package (see [[AppSuite:Running_a_cluster#Rolling_Upgrade_with_breaking_Hazelcast_upgrade]])&lt;br /&gt;
* Exclude the update tasks for both mentioned migrations (i.e. calendar and character encoding). See “Update Task Exclusion” for details.&lt;br /&gt;
* Execute update tasks according to your preferred strategy. More on this can be found at [[UpdateTasks]].&lt;br /&gt;
&lt;br /&gt;
By default (if using the &amp;quot;runallupdate&amp;quot; tool&amp;quot;) update tasks operate on database schemas sequentially, one at a time. All users from all contexts of a given schema are logged out and locked out. Then, DB schema changes are executed. Finally, users are unlocked and able to login again. Schemas typically contain a few thousand users (if our recommended sizing is being followed) and thus executing update tasks means bunches of a few thousand users will be affected sequentially. You will not have a full downtime. For each update task execution process the following statements hold true:&lt;br /&gt;
&lt;br /&gt;
* All users got service for nearly all the time (all the time but the time where their schema is upgraded)&lt;br /&gt;
* For each point in time, nearly all users got service (all but the ones from the currently updated schema)&lt;br /&gt;
* When update tasks are completed, all users will have been affected by one &amp;quot;logout&amp;quot; - &amp;quot;locked out&amp;quot; cycle&lt;br /&gt;
&lt;br /&gt;
After complete and successful update task execution, roll out OX App Suite v7.10.0 to one node after another. After complete rollout, reconfigure MySQL if appropriate as described in the “Database System” section.&lt;br /&gt;
&lt;br /&gt;
=== Update Task Exclusion ===&lt;br /&gt;
&lt;br /&gt;
Add the following lines to &amp;lt;code&amp;gt;/opt/open-xchange/etc/excludedupdatetasks.properties&amp;lt;/code&amp;gt; or remove the leading # character if already included, so that it contains these two lines:&lt;br /&gt;
&lt;br /&gt;
 # Character Encoding Migration&lt;br /&gt;
 com.openexchange.groupware.update.excludedUpdateTasks=groupware.utf8mb4&lt;br /&gt;
 &lt;br /&gt;
 # Calendar Migration&lt;br /&gt;
 com.openexchange.chronos.storage.rdb.migration.ChronosStorageMigrationTask&lt;br /&gt;
&lt;br /&gt;
The first line does not denote one dedicated update task, but a whole list of tasks. To make exclusion more convenient, the concept of update task namespaces has been introduced. All update tasks belonging to the character encoding migration are part of the &amp;lt;code&amp;gt;groupware.utf8mb4&amp;lt;/code&amp;gt; namespace. The denoted property takes care of excluding them all at once. You can list all according tasks with the &amp;lt;code&amp;gt;/opt/open-xchange/sbin/listUpdateTaskNamespaces&amp;lt;/code&amp;gt; tool.&lt;br /&gt;
&lt;br /&gt;
== Character Encoding Migration ==&lt;br /&gt;
&lt;br /&gt;
The default character encoding for Unicode (named character set by MySQL) of MySQL will become &amp;lt;code&amp;gt;utf8mb4&amp;lt;/code&amp;gt; in the near future. MariaDB on Debian Stretch (9) already has an according default configuration set when installing it from distribution packages. So far all VARCHAR columns are supposed to store at max. 3-byte UTF-8 characters due to the nature of MySQL’s utf8 character encoding. This leads to the fact that for example emojis cannot be saved as part of any App Suite entities. In a mixed-mode scenario (App Suite considers MySQL to operate in utf8mb4 mode due to the &amp;lt;code&amp;gt;character_set_server&amp;lt;/code&amp;gt; setting, while columns are specified with utf8 encoding), this leads to issues whenever certain collations during SELECT statements are enforced. To avoid such issues generally and also increase user experience by finally allowing characters from the Unicode astral plane, Open-Xchange has decided to migrate existing data structures to the utf8mb4 character encoding.&lt;br /&gt;
&lt;br /&gt;
This migration can be executed before or after the calendar migration, while it is recommend to execute it before.&lt;br /&gt;
&lt;br /&gt;
The upgrade procedure is basically the same as above in terms executing update tasks, while the server software is already up to date and needs no further upgrades:&lt;br /&gt;
&lt;br /&gt;
* Again prepare one dedicated node that doesn’t serve any user traffic&lt;br /&gt;
* Remove the according namespace property from &amp;lt;code&amp;gt;excludedupdatetasks.properties&amp;lt;/code&amp;gt; again, but still keep the “ChronosStorageMigrationTask”. Afterwards restart the open-xchange daemon.&lt;br /&gt;
* Execute update tasks according to your preferred strategy.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' The update tasks require a lot of tables to be copied and re-created, leading to high I/O and especially sequential read and write operations. For every copied table the needed MySQL disk space doubles during the update task, so ensure enough free space before running the migration.&lt;br /&gt;
&lt;br /&gt;
== Calendar Data Migration ==&lt;br /&gt;
&lt;br /&gt;
The new calendar stack in OX App Suite v7.10.0 comes along with a new data model using its very own tables in MySQL. To preserve users calendar data, an update task &amp;lt;code&amp;gt;com.openexchange.chronos.storage.rdb.migration.ChronosStorageMigrationTask&amp;lt;/code&amp;gt; has been introduced, that reads all data from the old tables, applies transformations to match the new stack and writes it into the new tables. The approach and upgrade process is described in detail at https://documentation.open-xchange.com/7.10.0/middleware/components/calendar/data_migration.html. Please read that article carefully before continuing. Especially we want to emphasize again the recommendation to test the migration with a copy of your real data to exclude or determine any issues beforehand.&lt;br /&gt;
&lt;br /&gt;
Before executing this update task, OX App Suite v7.10.0 uses the new calendar stack on top of the old database tables through a compatibility layer. As the old storage layout lacks certain functionality, not all features are functional in between the application upgrade and execution of the update task. Due to this fact, a few spots are affected where not all appointment data that the user interface allows to enter can be persisted. This includes:&lt;br /&gt;
&lt;br /&gt;
* Reminders, where still only one notification prior the appointment start is possible&lt;br /&gt;
* Colors, that cannot be mapped to the previously used labels&lt;br /&gt;
* 4-byte UTF-8 characters (emojis) are not yet possible&lt;br /&gt;
* Secret appointments, that are still stored as private ones&lt;br /&gt;
* An appointment's end timezone can't be applied, if it's different from the start timezone&lt;br /&gt;
&lt;br /&gt;
Operators of ''non-Galera'' MySQL setups - i.e. Master-Slave replication - can potentially speed up the migration by configuring &amp;lt;code&amp;gt;com.openexchange.calendar.migration.intermediateCommits = false&amp;lt;/code&amp;gt;. Per default the migration is performed in batches that separately committed, as Galera does not cope well with large transactions. By changing the setting to &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;, a single transaction with batch-mode enabled is used.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' The migrating of calendar data actually leads to a duplication of that data. Also with OX App Suite v7.10.0 every new calendar data is written to both, the old and the new tables redundantly to preserve to ability to roll back to OX App Suite v7.8.4. However, only the parts can preserved that match the old data model. I.e. additional features like multiple reminders or subscriptions of external calendars (Google Calendar, SchedJoules) cannot be preserved during a rollback.&lt;br /&gt;
&lt;br /&gt;
A repeated OX App Suite v7.10.0 upgrade after a former rollback to OX App Suite v7.8.4 requires to force re-execution of this update task!&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:7_10_Database_Migration&amp;diff=24174</id>
		<title>AppSuite:7 10 Database Migration</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:7_10_Database_Migration&amp;diff=24174"/>
		<updated>2018-07-18T11:13:14Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Initial OX App Suite v7.10.0 Rollout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Version|7.10.0}}&lt;br /&gt;
&lt;br /&gt;
= Database Migration with OX App Suite v7.10.0 =&lt;br /&gt;
&lt;br /&gt;
OX App Suite v7.10.0 introduces significant changes regarding the underlying MySQL database system that require special attention in case of upgrades from former versions. Please read this paper carefully to ensure a smooth and clean upgrade process.&lt;br /&gt;
&lt;br /&gt;
== Change Overview ==&lt;br /&gt;
&lt;br /&gt;
The most significant changes are:&lt;br /&gt;
* New version and configuration requirements.&lt;br /&gt;
* Most VARCHAR columns need to be migrated to utf8mb4 character encoding.&lt;br /&gt;
* A major rewrite of the calendar application requires full data migration.&lt;br /&gt;
&lt;br /&gt;
We strongly recommend to thoroughly plan and test the upgrade procedure. To gain insights about update task runtimes and the expected load, our recommendation is to clone ConfigDB and the biggest UserDB and perform an isolated test upgrade that especially covers the calendar migration and character encoding changes. Update task durations can be significantly longer than with previous upgrades and the migrations might cause noticeable higher I/O load. Also some additional disk space is needed during and after the migrations.&lt;br /&gt;
&lt;br /&gt;
== Database System ==&lt;br /&gt;
&lt;br /&gt;
MySQL Server is supported in versions 5.6 and 5.7 with recent patch levels only and MariaDB Server 10.1 and 10.2 respectively. Support for 5.6/10.1 exists for compatibility reasons and is transitional. We recommend upgrading to 5.7/10.2 as soon as possible. Any database system upgrade must happen before App Suite is upgraded to OX App Suite v7.10.0. Please follow the respective guides of your database vendor carefully.&lt;br /&gt;
&lt;br /&gt;
Different App Suite and database system versions require different configurations of the DBMS, please follow http://oxpedia.org/wiki/index.php?title=My.cnf to have your database configured in a sane way. Especially the following items require some attention with the upgrade to App Suite 7.10.0 and upgrades of the DBMS itself:&lt;br /&gt;
&lt;br /&gt;
* Supported SQL modes are only &amp;lt;code&amp;gt;NO_ENGINE_SUBSTITUTION&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;NO_AUTO_CREATE_USER&amp;lt;/code&amp;gt;. Starting with App Suite 7.10.0, &amp;lt;code&amp;gt;ONLY_FULL_GROUP_BY&amp;lt;/code&amp;gt; is also supported for MySQL 5.7. It is still not with older versions of MySQL or any MariaDB version! To review the current value, use &amp;lt;code&amp;gt;SHOW GLOBAL VARIABLES WHERE Variable_name = 'sql_mode';&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Ensure that &amp;lt;code&amp;gt;character_set_server&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;utf8&amp;lt;/code&amp;gt; for App Suite 7.8.x. Again the current global default value can be obtained via &amp;lt;code&amp;gt;SHOW GLOBAL VARIABLES WHERE Variable_name = 'character_set_server';&amp;lt;/code&amp;gt;. With 7.10.0 being fully rolled out, this setting must then be changed to &amp;lt;code&amp;gt;utf8mb4&amp;lt;/code&amp;gt;. If &amp;lt;code&amp;gt;collation_server&amp;lt;/code&amp;gt; is configured explicitly, it must be set to a matching value according to the character set in either case!&lt;br /&gt;
&lt;br /&gt;
Note that App Suite &amp;lt;= 7.8.4 did not support MySQL 5.7/MariaDB 10.2 so far. While we recommend it for 7.10.0, this leaves a lack of definition during the upgrade process. We consider running 7.8.4 on top of MySQL 5.7/MariaDB 10.2 a valid scenario as long as it is transitional during the upgrade phase. Please take our configuration recommendations seriously to mitigate potential user-facing issues as far as possible.&lt;br /&gt;
&lt;br /&gt;
== Upgrade Procedure ==&lt;br /&gt;
&lt;br /&gt;
The upgrade to OX App Suite v7.10.0 can be performed like any other major upgrade before. However, the duration of blocking database update tasks for the mentioned charset and calendar migrations could conflict with customers’ availability demands. Therefore it is possible to decouple these special time- and resource-intensive tasks from the plain version upgrade. In this section a multi-step approach is described that performs the version upgrade before and independently from the migrations. Every step always results in a working system that is ready to serve user traffic. Some functional implications that affect user experience are outlined in the according subsections.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' Even though the first step leads to a basically working OX App Suite v7.10.0 environment, the subsequent steps are not optional but mandatory! Skipping the migrations will leave a few calendar features dysfunctional and can lead to issues with certain SQL queries that use explicit collations for searching and sorting. Running OX App Suite v7.10.0 in production without having all parts of the migration fulfilled is not supported – OX support will request you to complete the migration tasks when reporting issues that are not related to the migration itself. &lt;br /&gt;
&lt;br /&gt;
== Initial OX App Suite v7.10.0 Rollout ==&lt;br /&gt;
If not done so far, upgrade your MySQL installation to a version supported with OX App Suite v7.10.0 but configure it to be compatible with OX App Suite v7.8.x as described in the “Database System” section.&lt;br /&gt;
&lt;br /&gt;
Despite the fact that the two special migrations for calendar and character sets are explicitly skipped, this section assumes that the “Rolling Upgrade with breaking Hazelcast upgrade” is applied as described in [[AppSuite:Running_a_cluster#Updating_a_Cluster]]. For the application server upgrade, the common guide from [[AppSuite:UpdatingOXPackages]] can be followed.&lt;br /&gt;
&lt;br /&gt;
Prepare a dedicated App Suite middleware node that will be used to perform the database update tasks. The node must not be serving any user traffic and be prepared with&lt;br /&gt;
&lt;br /&gt;
* OX App Suite v7.10.0 packages&lt;br /&gt;
* Configuration according to the user production nodes&lt;br /&gt;
* The Hazelcast rolling upgrade compatibility package (see [[AppSuite:Running_a_cluster#Rolling_Upgrade_with_breaking_Hazelcast_upgrade]])&lt;br /&gt;
* Exclude the update tasks for both mentioned migrations (i.e. calendar and character encoding). See “Update Task Exclusion” for details.&lt;br /&gt;
* Execute update tasks according to your preferred strategy. More on this can be found at [[UpdateTasks]].&lt;br /&gt;
&lt;br /&gt;
By default (if using the &amp;quot;runallupdate&amp;quot; tool&amp;quot;) update tasks operate on database schemas sequentially, one at a time. All users from all contexts of a given schema are logged out and locked out. Then, DB schema changes are executed. Finally, users are unlocked and able to login again. Schemas typically contain a few thousand users (if our recommended sizing is being followed) and thus executing update tasks means bunches of a few thousand users will be affected sequentially. You will not have a full downtime. For each update task execution process the following statements hold true:&lt;br /&gt;
&lt;br /&gt;
* All users got service for nearly all the time (all the time but the time where their schema is upgraded)&lt;br /&gt;
* For each point in time, nearly all users got service (all but the ones from the currently updated schema)&lt;br /&gt;
* When update tasks are completed, all users will have been affected by one &amp;quot;logout&amp;quot; - &amp;quot;locked out&amp;quot; cycle&lt;br /&gt;
&lt;br /&gt;
After complete and successful update task execution, roll out OX App Suite v7.10.0 to one node after another. After complete rollout, reconfigure MySQL if appropriate as described in the “Database System” section.&lt;br /&gt;
&lt;br /&gt;
=== Update Task Exclusion ===&lt;br /&gt;
&lt;br /&gt;
Add the following lines to &amp;lt;code&amp;gt;/opt/open-xchange/etc/excludedupdatetasks.properties&amp;lt;/code&amp;gt; or remove the leading # character if already included, so that it contains these two lines:&lt;br /&gt;
&lt;br /&gt;
 # Character Encoding Migration&lt;br /&gt;
 com.openexchange.groupware.update.excludedUpdateTasks=groupware.utf8mb4&lt;br /&gt;
 &lt;br /&gt;
 # Calendar Migration&lt;br /&gt;
 com.openexchange.chronos.storage.rdb.migration.ChronosStorageMigrationTask&lt;br /&gt;
&lt;br /&gt;
The first line does not denote one dedicated update task, but a whole list of tasks. To make exclusion more convenient, the concept of update task namespaces has been introduced. All update tasks belonging to the character encoding migration are part of the &amp;lt;code&amp;gt;groupware.utf8mb4&amp;lt;/code&amp;gt; namespace. The denoted property takes care of excluding them all at once. You can list all according tasks with the &amp;lt;code&amp;gt;/opt/open-xchange/sbin/listUpdateTaskNamespaces&amp;lt;/code&amp;gt; tool.&lt;br /&gt;
&lt;br /&gt;
== Character Encoding Migration ==&lt;br /&gt;
&lt;br /&gt;
The default character encoding for Unicode (named character set by MySQL) of MySQL will become &amp;lt;code&amp;gt;utf8mb4&amp;lt;/code&amp;gt; in the near future. MariaDB on Debian Stretch (9) already has an according default configuration set when installing it from distribution packages. So far all VARCHAR columns are supposed to store at max. 3-byte UTF-8 characters due to the nature of MySQL’s utf8 character encoding. This leads to the fact that for example emojis cannot be saved as part of any App Suite entities. In a mixed-mode scenario (App Suite considers MySQL to operate in utf8mb4 mode due to the &amp;lt;code&amp;gt;character_set_server&amp;lt;/code&amp;gt; setting, while columns are specified with utf8 encoding), this leads to issues whenever certain collations during SELECT statements are enforced. To avoid such issues generally and also increase user experience by finally allowing characters from the Unicode astral plane, Open-Xchange has decided to migrate existing data structures to the utf8mb4 character encoding.&lt;br /&gt;
&lt;br /&gt;
This migration can be executed before or after the calendar migration, while it is recommend to execute it before.&lt;br /&gt;
&lt;br /&gt;
The upgrade procedure is basically the same as above in terms executing update tasks, while the server software is already up to date and needs no further upgrades:&lt;br /&gt;
&lt;br /&gt;
* Again prepare one dedicated node that doesn’t serve any user traffic&lt;br /&gt;
* Remove the according namespace property from &amp;lt;code&amp;gt;excludedupdatetasks.properties&amp;lt;/code&amp;gt; again, but still keep the “ChronosStorageMigrationTask”. Afterwards restart the open-xchange daemon.&lt;br /&gt;
* Execute update tasks according to your preferred strategy.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' The update tasks require a lot of tables to be copied and re-created, leading to high I/O and especially sequential read and write operations. For every copied table the needed MySQL disk space doubles during the update task, so ensure enough free space before running the migration.&lt;br /&gt;
&lt;br /&gt;
== Calendar Data Migration ==&lt;br /&gt;
&lt;br /&gt;
The new calendar stack in OX App Suite v7.10.0 comes along with a new data model using its very own tables in MySQL. To preserve users calendar data, an update task &amp;lt;code&amp;gt;com.openexchange.chronos.storage.rdb.migration.ChronosStorageMigrationTask&amp;lt;/code&amp;gt; has been introduced, that reads all data from the old tables, applies transformations to match the new stack and writes it into the new tables. The approach and upgrade process is described in detail at https://documentation.open-xchange.com/7.10.0/middleware/components/calendar/data_migration.html. Please read that article carefully before continuing. Especially we want to emphasize again the recommendation to test the migration with a copy of your real data to exclude or determine any issues beforehand.&lt;br /&gt;
&lt;br /&gt;
Before executing this update task, OX App Suite v7.10.0 uses the new calendar stack on top of the old database tables through a compatibility layer. As the old storage layout lacks certain functionality, not all features are functional in between the application upgrade and execution of the update task. Due to this fact, a few spots are affected where not all appointment data that the user interface allows to enter can be persisted. This includes:&lt;br /&gt;
&lt;br /&gt;
* Reminders, where still only one notification prior the appointment start is possible&lt;br /&gt;
* Colors, that cannot be mapped to the previously used labels&lt;br /&gt;
* 4-byte UTF-8 characters (emojis) are not yet possible&lt;br /&gt;
* Secret appointments, that are still stored as private ones&lt;br /&gt;
* An appointment's end timezone can't be applied, if it's different from the start timezone&lt;br /&gt;
&lt;br /&gt;
Operators of ''non-Galera'' MySQL setups - i.e. Master-Slave replication - can potentially speed up the migration by configuring &amp;lt;code&amp;gt;com.openexchange.calendar.migration.intermediateCommits = false&amp;lt;/code&amp;gt;. Per default the migration is performed in batches that separately committed, as Galera does not cope well with large transactions. By changing the setting to &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;, a single transaction with batch-mode enabled is used.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' The migrating of calendar data actually leads to a duplication of that data. Also with OX App Suite v7.10.0 every new calendar data is written to both, the old and the new tables redundantly to preserve to ability to roll back to OX App Suite v7.8.4. However, only the parts can preserved that match the old data model. I.e. additional features like multiple reminders or subscriptions of external calendars (Google Calendar, SchedJoules) cannot be preserved during a rollback.&lt;br /&gt;
&lt;br /&gt;
A repeated OX App Suite v7.10.0 upgrade after a former rollback to OX App Suite v7.8.4 requires to force re-execution of this update task!&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:OX_System_Requirements&amp;diff=24173</id>
		<title>AppSuite:OX System Requirements</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:OX_System_Requirements&amp;diff=24173"/>
		<updated>2018-07-18T07:02:25Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Important Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= OX App Suite Requirements - Open-Xchange supported components overview =&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview about the supported components at the OX User Front-End, Connector for Microsoft Outlook and Connector for Business Mobility. This overview makes no claim to be complete.&lt;br /&gt;
&lt;br /&gt;
Open-Xchange Server 6 overview tables about the supported components at the OX User Front-End, Connector for Microsoft Outlook and Connector for Business Mobility are available at [[OX_System_Requirements|OX 6 Requirements - Open-Xchange supported components overview]]&lt;br /&gt;
&lt;br /&gt;
Information about Maintenance expiries of components, versions and browser support, can be found in the [[AppSuite:Versioning_and_Numbering#Maintenance_expires|Maintenance Expires Table]]&lt;br /&gt;
&lt;br /&gt;
== Hardware Requirements ==&lt;br /&gt;
=== General Assumptions ===&lt;br /&gt;
Open-Xchange App Suite Server (middleware services) is designed to run on physical servers or virtual machines of the same flavor. Cloud environments might be used in terms of Infrastructure as a Service (IaaS), meaning that all components need to be deployed in a classical manner on virtual machines.&lt;br /&gt;
&lt;br /&gt;
This means in particular, but not only:&lt;br /&gt;
&lt;br /&gt;
* Infrastructure is &amp;quot;quasi-static&amp;quot;. We don't need to take into account things like VMs coming and going dynamically, dynamic IPs, volatile (&amp;quot;ephemeral&amp;quot;) data&lt;br /&gt;
* &amp;quot;Database as a service&amp;quot; is not allowed. This typically is a highly customized &amp;quot;MySQL like&amp;quot; storage engine, and not a true MySQL, and we can't control flavor, version, setup, etc. If need for configuration changes is identified, we won't be able to change anything.&lt;br /&gt;
&lt;br /&gt;
So to summarize: we expect any virtualized platform to behave and work just like a well-known non-virtualized / physical platform.&lt;br /&gt;
&lt;br /&gt;
Especially we expect the virtual hardware to be not over-provisioned. Each VM must have dedicated resources with respect to CPU cores, RAM, IOPS, storage, network bandwidth, network latency, etc.&lt;br /&gt;
&lt;br /&gt;
Network is expected to be flat, inside one datacenter, no multi-datacenter, no segments. No packet loss, low latency.&lt;br /&gt;
&lt;br /&gt;
'''Disclaimer: All recommendations below are without guarantee and can differ for specific deployments. For mid- and large-scale setups a detailed deployment planning and sizing tests are mandatory and should be agreed on with OX Professional Services.'''&lt;br /&gt;
&lt;br /&gt;
=== High Level Design / OS setup ===&lt;br /&gt;
Operate services separately (USM, Document/Image Converters) as described in Cluster Setup.&lt;br /&gt;
&lt;br /&gt;
Clocks between all nodes must be synchronized (e.g. via NTP).&lt;br /&gt;
&lt;br /&gt;
Open file/max process limits need to be adjusted properly. Based on the used Linux distribution and init system configuration will differ, see Resource Limits for further explanation.&lt;br /&gt;
&lt;br /&gt;
Platform Architecture: 64 bit versions (x84_64) of the supported [[#Software Requirements | Linux distributions]]&lt;br /&gt;
&lt;br /&gt;
=== Node Sizing ===&lt;br /&gt;
* Max. 8 GB heap per JVM + 4 GB system memory for other daemons and the OS (buffers, caches)&lt;br /&gt;
* 4 CPU cores (virtual, physical or hyperthreads)&lt;br /&gt;
* Disk space&lt;br /&gt;
** 5 GB for OS and software&lt;br /&gt;
** &amp;lt;code&amp;gt;2 * system memory&amp;lt;/code&amp;gt; of free disk space (i.e. 12 GB RAM =&amp;gt; 24 GB free disk space) for file spooling, log files, heap and core dumps&lt;br /&gt;
&lt;br /&gt;
=== Untested/Unsupported Deployments ===&lt;br /&gt;
* Changes to Garbage Collector settings&lt;br /&gt;
* Running in containerized environments (Docker, rkt)&lt;br /&gt;
* Elasticity/High velocity of nodes going up and down: Services are sometimes stateful and demand static configuration&lt;br /&gt;
* Cloud platform services (PaaS) like database systems (for example AWS RDS)&lt;br /&gt;
* Multi-site active-active&lt;br /&gt;
&lt;br /&gt;
== Software Requirements ==&lt;br /&gt;
&lt;br /&gt;
=== Linux Distributions ===&lt;br /&gt;
&lt;br /&gt;
OX App Suite is available as Linux packages for the following distributions:&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
 |'''Distribution'''&lt;br /&gt;
 |'''Versions'''&lt;br /&gt;
 |'''Derivates'''&lt;br /&gt;
|- &lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
 |Suse Linux Enterprise Server&lt;br /&gt;
 |12&lt;br /&gt;
 |None&lt;br /&gt;
|-&lt;br /&gt;
 |Red Hat Enterprise Linux&lt;br /&gt;
 |6,7&lt;br /&gt;
 |CentOS&lt;br /&gt;
|-&lt;br /&gt;
 |Debian&lt;br /&gt;
 |8 (Jessie), 9 (stretch)&lt;br /&gt;
 |None&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&lt;br /&gt;
OX App Suite Middleware requires OpenJDK headless JRE 8 or 9.&lt;br /&gt;
&lt;br /&gt;
'''Please note:''' For Debian 8 (Jessie) OpenJDK 8 is only available via the [https://packages.debian.org/search?keywords=jessie-backports jessie-backports] repository.&lt;br /&gt;
&lt;br /&gt;
=== Databases ===&lt;br /&gt;
&lt;br /&gt;
OX App Suite uses MySQL with the InnoDB storage engine as its primary data store. The following vendors and products are supported.&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
 |'''Vendor'''&lt;br /&gt;
 |'''Product'''&lt;br /&gt;
 |'''Versions'''&lt;br /&gt;
|- &lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
 |Oracle&lt;br /&gt;
 |MySQL Community Edition, Standard Edition, Enterprise Edition&lt;br /&gt;
 |[5.6.x, 5.7.x]&lt;br /&gt;
|-&lt;br /&gt;
 |MariaDB&lt;br /&gt;
 |MariaDB Server, Galera Cluster&lt;br /&gt;
 |[10.1.x, 10.2.x]&lt;br /&gt;
|-&lt;br /&gt;
 |Percona&lt;br /&gt;
 |XtraDB Cluster&lt;br /&gt;
 |[5.6.x, 5.7.x]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Important Notes ===&lt;br /&gt;
&lt;br /&gt;
* For some Linux distributions the included MySQL/MariaDB packages are too old to be used with App Suite. It is mandatory then to install a supported version from upstream package sources. Possible sources are the official vendor repositories of MySQL, MariaDB or Percona as well as for example Red Hat Software Collections.&lt;br /&gt;
* Required MySQL configuration differs between App Suite 7.8.4 and 7.10.0 and also between the different database systems in terms of SQL modes. See [[My.cnf]] for details.&lt;br /&gt;
* For upgrades to App Suite 7.10.0 a comprehensive database upgrade guide exists: [[AppSuite:7_10_Database_Migration]]&lt;br /&gt;
&lt;br /&gt;
== File Storage ==&lt;br /&gt;
&lt;br /&gt;
=== Temporary Data ===&lt;br /&gt;
&lt;br /&gt;
OX App Suite stores temporary files in the local file system, e.g. for spooling of uploaded data. Any file system supported by the installed JRE is suitable.&lt;br /&gt;
&lt;br /&gt;
=== Persistent Data ===&lt;br /&gt;
&lt;br /&gt;
Persistent data like OX Drive files, PIM attachments etc. needs to be stored in a distributed file system that is available from all server nodes. For single-node setups a local file system mount point can be used, small to mid-scale setups can be powered by NFS. For large-scale setups object storages should be considered.&lt;br /&gt;
&lt;br /&gt;
==== Object Storages ====&lt;br /&gt;
&lt;br /&gt;
OX App Suite ships with different optional adapters to support object storages.&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
 |'''Vendor'''&lt;br /&gt;
 |'''Product'''&lt;br /&gt;
 |'''API'''&lt;br /&gt;
 |'''Remarks'''&lt;br /&gt;
|- &lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
 |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
 |Amazon&lt;br /&gt;
 |AWS S3&lt;br /&gt;
 |S3 HTTP API&lt;br /&gt;
 |See also http://oxpedia.org/wiki/index.php?title=AppSuite:S3_File_Store&lt;br /&gt;
|-&lt;br /&gt;
 |CEPH&lt;br /&gt;
 |RadosGW&lt;br /&gt;
 |S3 HTTP API&lt;br /&gt;
 |See also http://oxpedia.org/wiki/index.php?title=AppSuite:S3_File_Store&lt;br /&gt;
|-&lt;br /&gt;
 |Scality&lt;br /&gt;
 |Scality RING&lt;br /&gt;
 |Sproxyd HTTP API&lt;br /&gt;
 |See also http://oxpedia.org/wiki/index.php?title=AppSuite:Scality_File_Store&lt;br /&gt;
|-&lt;br /&gt;
 |OpenStack&lt;br /&gt;
 |Swift&lt;br /&gt;
 |Object Storage API V1&lt;br /&gt;
 |Support for Swift is experimental and could be removed again in the future. See also http://oxpedia.org/wiki/index.php?title=AppSuite:Swift_File_Store&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Desktop Browser (Minimum display resolution: 1024 x 768)==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Browser'''&lt;br /&gt;
  |'''OX App Suite User Front-End'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Microsoft Internet Explorer 10/11&lt;br /&gt;
  |v7.6.3&lt;br /&gt;
|-&lt;br /&gt;
  |Microsoft Internet Explorer 11/Edge&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Mozilla Firefox (latest &amp;amp; previous version)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Google Chrome (latest &amp;amp; previous version)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Apple Safari (10.01 &amp;amp; 10.03; Mac OS X only)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Mobile Device Support==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Mobile Device'''&lt;br /&gt;
  |'''Supported Browser'''&lt;br /&gt;
  |'''OX App Suite User Front-End'''&lt;br /&gt;
  |'''Minimum Speed Requirements'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |iPhone on iOS 10 / iOS 11&lt;br /&gt;
  |Safari&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
  |3G connections (512/256kBit/s, 350ms latency)&lt;br /&gt;
 |-&lt;br /&gt;
  |Smartphone on Android 4.1 or later&lt;br /&gt;
  |Chrome (latest &amp;amp; previous version)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
  |3G connections (512/256kBit/s, 350ms latency)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tablet Support==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Tablet'''&lt;br /&gt;
  |'''Supported Browser'''&lt;br /&gt;
  |'''OX App Suite User Front-End'''&lt;br /&gt;
  |'''Minimum Speed Requirements'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Apple iPad (all devices) on iOS 10 / iOS 11&lt;br /&gt;
  |Safari&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
  |3G connections (512/256kBit/s, 350ms latency)&lt;br /&gt;
 |-&lt;br /&gt;
  |Tablets on Android 4.1 or later&lt;br /&gt;
  |Chrome (latest &amp;amp; previous version)&lt;br /&gt;
  |v7.8.4, v7.10.0&lt;br /&gt;
  |3G connections (512/256kBit/s, 350ms latency)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Calendar/Contact synchronization Apple Mac OS X ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |Calendar synchronization with CalDAV&lt;br /&gt;
  |Contacts synchronization with CardDAV&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
  |Mac OS X 10.11 (El Capitan)&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
|-&lt;br /&gt;
  |macOS 10.12, 10.13 (Sierra &amp;amp; High Sierra)&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Calendar/Contact synchronization Apple iOS ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |Calendar synchronization with CalDAV&lt;br /&gt;
  |Contacts synchronization with CardDAV&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
  |Apple iOS 10 / iOS 11&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Mobility Solution - Supported-  Platforms, Features and Devices ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Feature/Technology/Device'''&lt;br /&gt;
  |[http://oxpedia.org/wiki/index.php?title=OXtender_for_Business_Mobility '''OXtender for Business Mobility'''] (availalble for App Suite, OXHE, OXSE)&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Exchange Active Sync 2.5&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |-&lt;br /&gt;
  |Exchange Active Sync 12.1&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Access and creation of emails&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
|-&lt;br /&gt;
  |Personal PIM folder&lt;br /&gt;
  |[[File:check.gif]] &lt;br /&gt;
|-&lt;br /&gt;
  |Public and Shared PIM folder&lt;br /&gt;
  |[[File:cross.gif]]&lt;br /&gt;
|-&lt;br /&gt;
  |Global address book&lt;br /&gt;
  |[[File:check.gif]] &lt;br /&gt;
|-&lt;br /&gt;
  |Push E-Mail&lt;br /&gt;
  |[[File:check.gif]] &lt;br /&gt;
|-&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |Windows Phone 8 (latest &amp;amp; previous minor versions), Windows Phone 10 (latest &amp;amp; previous minor versions)&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |-&lt;br /&gt;
  |Apple iOS 10 / iOS 11&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |-&lt;br /&gt;
  |Android 4.1 or later&lt;br /&gt;
  |[[File:check.gif]]&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Drive for Clients ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX App Suite v7.8.4, OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Drive for Windows&lt;br /&gt;
  |Latest versions of Windows 8, latest versions of Windows 10 (no support of Mac OS X clients with emulators and Windows RT)&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Drive for Mac OS&lt;br /&gt;
  |Mac OS X 10.11 (El Capitan), macOS 10.12, 10.13 (Sierra &amp;amp; High Sierra)&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Drive for iOS&lt;br /&gt;
  |Apple iOS 10, Apple iOS 11&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Drive for Android&lt;br /&gt;
  |Smartphone on Android 4.1 or later with Chrome (latest &amp;amp; previous version), Tablets on Android 4.1 or later with Chrome (latest &amp;amp; previous version)&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Mail App ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform / User Interface'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX App Suite v7.8.4, OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Mail for iOS&lt;br /&gt;
  |Apple iOS 10, Apple iOS 11&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Mail for Android&lt;br /&gt;
  |Smartphone on Android 4.3 or later&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Mail App v2 ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform / User Interface'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |[http://oxpedia.org/wiki/index.php?title=AppSuite:Main_Page_Quickinstall#Quick_Installation_Guide OX App Suite]&lt;br /&gt;
  |OX App Suite v7.8.4 or later&lt;br /&gt;
 |-&lt;br /&gt;
  |[http://oxpedia.org/wiki/index.php?title=AppSuite:Mobile_API_Facade Mobile API Facade]&lt;br /&gt;
  |Mobile API Facade v1.0.2 or later (until OX App Suite v7.8.4)&amp;lt;br&amp;gt;Mobile API Facade v1.2.0 or later (from OX App Suite v7.10.0)&lt;br /&gt;
 |-&lt;br /&gt;
  |Push Notification Package&lt;br /&gt;
  |Package &amp;quot;open-xchange-mobile-api-facade-push-certificates&amp;quot; (available to App Suite licensees only)&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Mail App v2.0 for iOS&lt;br /&gt;
  |Apple iOS 9.3, iOS 10, iOS 11 &amp;lt;br&amp;gt;Server reachable via TLS 1.2&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Mail App v2.0 for Android&lt;br /&gt;
  |Android 5.0 (Lollipop) or higher&amp;lt;br&amp;gt;Server reachable via TLS 1.2&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Sync App ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform / User Interface'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX App Suite v7.8.4, OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |OX Sync App for Android&lt;br /&gt;
  |Smartphone on Android 4.0 or later&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== OX Guard ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |'''System / Platform / User Interface'''&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX Guard since v2.6.0: OX App Suite v7.8.3&amp;lt;br&amp;gt;OX Guard since v2.8.0: OX App Suite v7.8.4&amp;lt;br&amp;gt;OX Guard since v2.10.0: OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Mobile Device and Tablet Support&lt;br /&gt;
  |Apple iPhone on iOS 10 / iOS 11: Safari (latest version &amp;amp; previous version)&amp;lt;br&amp;gt;Smartphone on Android 4.1 or later: Chrome (latest &amp;amp; previous version)&amp;lt;br&amp;gt;Apple iPad (all devices) on iOS 10 / iOS 11: Safari Safari (latest version &amp;amp; previous version)&amp;lt;br&amp;gt;Tablets on Android 4.1 or later: Chrome (latest &amp;amp; previous version)&lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== eM Client for OX App Suite ==&lt;br /&gt;
&lt;br /&gt;
 {|border=&amp;quot;2&amp;quot; rules=&amp;quot;all&amp;quot; align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  |'''Requirement'''&lt;br /&gt;
  |[http://oxpedia.org/wiki/index.php?title=AppSuite:EM_Client_for_OX_App_Suite '''eM Client for OX App Suite''']&lt;br /&gt;
 |- &lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
  |&amp;amp;nbsp;&lt;br /&gt;
 |-&lt;br /&gt;
  |OX App Suite&lt;br /&gt;
  |OX App Suite v7.8.4, OX App Suite v7.10.0&lt;br /&gt;
 |-&lt;br /&gt;
  |Client PC operating system&lt;br /&gt;
  |Latest versions of Windows 8 (no support of start screen tiles), latest versions of Windows 10 (no support of Mac OS X clients with emulators and Windows RT)&lt;br /&gt;
  |-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: OX7]]&lt;br /&gt;
[[Category: AppSuite]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Configuring_portal_plugins&amp;diff=24064</id>
		<title>AppSuite:Configuring portal plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Configuring_portal_plugins&amp;diff=24064"/>
		<updated>2018-06-26T06:03:35Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- !!! --&amp;gt;&lt;br /&gt;
&amp;lt;!-- PLEASE APPLY CHANGES ONLY TO THE NEW TECHNICAL DOCUMENTATION: wd/frontend/web/documentation --&amp;gt; &lt;br /&gt;
&amp;lt;!-- !!! --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Stability-stable}}&lt;br /&gt;
{{VersionFrom|7.4.0}}&lt;br /&gt;
&lt;br /&gt;
= Configuring portal plugins =&lt;br /&gt;
&lt;br /&gt;
''Synopsis:'' This article covers how to configure which plugins (&amp;quot;tiles&amp;quot;) are shown, whether they are mandatory or just suggested to the user.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Configuring the portal ==&lt;br /&gt;
&lt;br /&gt;
When running OX AppSuite you may want to specify a starting configuration for which tiles the portal shows and whether certain tiles are mandatory or not. This is especially useful when you are introducing your own tile implementations. To make this possible, the portal consists of three types of tiles: User tiles, eager tiles and protected tiles. User tiles are tiles that the user added herself to the portal page, eager tiles are those suggested by the installation which can be removed and protected tiles are set by the backend. &lt;br /&gt;
&lt;br /&gt;
In order to specify a tile, you will have to know about the configuration data to enter. You can use an appsuite installation to do that. If you want to configure a tile as eager or protected, navigate to the settings area of the portal page, add the tile you want and, in the JS console, enter:&lt;br /&gt;
&lt;br /&gt;
 require(&amp;quot;settings!io.ox/portal&amp;quot;).get(&amp;quot;widgets/user&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
and in the list find the tile you want to suggest to or force on your users. As an example, we'll use the birthday widget:&lt;br /&gt;
&lt;br /&gt;
 birthdays_0: Object&lt;br /&gt;
    color: &amp;quot;lightgreen&amp;quot;&lt;br /&gt;
    enabled: true&lt;br /&gt;
    id: &amp;quot;birthdays_0&amp;quot;&lt;br /&gt;
    index: 6&lt;br /&gt;
    inverse: false&lt;br /&gt;
    plugin: &amp;quot;plugins/portal/birthdays/register&amp;quot;&lt;br /&gt;
    props: Object&lt;br /&gt;
    type: &amp;quot;birthdays&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In order to configure widgets on the backend we have to turn the above into a valid YAML structure:&lt;br /&gt;
&lt;br /&gt;
 birthdays_0:&lt;br /&gt;
    color: &amp;quot;lightgreen&amp;quot; # one of black, red, orange, lightgreen, &lt;br /&gt;
                        # green, lightblue, blue, purple, pink, gray&lt;br /&gt;
    enabled: true       # Has to be true &lt;br /&gt;
    index: &amp;quot;first&amp;quot;      # Where the widget is supposed to show up. &lt;br /&gt;
                        # Possible values are numbers, &amp;quot;first&amp;quot; or &lt;br /&gt;
                        # &amp;quot;last&amp;quot; &lt;br /&gt;
    inverse: false      # If true, the color is applied to the body &lt;br /&gt;
                        # of the tile and not the title. Can highlight &lt;br /&gt;
                        # particular tiles&lt;br /&gt;
    plugin: &amp;quot;plugins/portal/birthdays/register&amp;quot; # The source file that contains the tile code&lt;br /&gt;
    type: &amp;quot;birthdays&amp;quot;   # The id of the widget type. Not the id above &lt;br /&gt;
                        # has to have the form [type]_[someNumber]&lt;br /&gt;
&lt;br /&gt;
Now we can use this snippet to configure the birthday widget in a variety of ways&lt;br /&gt;
&lt;br /&gt;
== I want to suggest a widget, but the user can remove it, if they don't like it ==&lt;br /&gt;
&lt;br /&gt;
For this, you can use the &amp;quot;eager&amp;quot; configuration method. Not that if you specify an eager or protected widget, all default widgets from Open-Xchange will not be configured as defaults anymore, so you might want to configure them as eager tiles as well. But let's stick to the birthday widget for now. &lt;br /&gt;
&lt;br /&gt;
* Add a file /opt/open-xchange/etc/settings/portal.yml&lt;br /&gt;
&lt;br /&gt;
 io.ox/portal//widgets/eager/gen_0:&lt;br /&gt;
    birthdays_0:&lt;br /&gt;
        color: &amp;quot;lightgreen&amp;quot;&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: &amp;quot;first&amp;quot;&lt;br /&gt;
        inverse: false&lt;br /&gt;
        plugin: &amp;quot;plugins/portal/birthdays/register&amp;quot;&lt;br /&gt;
        type: &amp;quot;birthdays&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This means the widget will be enabled for users, but users can still disable it. If you want to, at a later time and since you've made significant improvements to the tile, want to show it to the user again, you have to increase the &amp;quot;generation&amp;quot; of the widget configuration and offer it again:&lt;br /&gt;
&lt;br /&gt;
 io.ox/portal/:&lt;br /&gt;
    generation: 1&lt;br /&gt;
&lt;br /&gt;
 io.ox/portal//widgets/eager/gen_0:&lt;br /&gt;
    birthdays_0:&lt;br /&gt;
        color: &amp;quot;lightgreen&amp;quot;&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: &amp;quot;first&amp;quot;&lt;br /&gt;
        inverse: false&lt;br /&gt;
        plugin: &amp;quot;plugins/portal/birthdays/register&amp;quot;&lt;br /&gt;
        type: &amp;quot;birthdays&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 io.ox/portal//widgets/eager/gen_1:&lt;br /&gt;
    birthdays_0:&lt;br /&gt;
        color: &amp;quot;lightgreen&amp;quot;&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: &amp;quot;first&amp;quot;&lt;br /&gt;
        inverse: false&lt;br /&gt;
        plugin: &amp;quot;plugins/portal/birthdays/register&amp;quot;&lt;br /&gt;
        type: &amp;quot;birthdays&amp;quot;&lt;br /&gt;
&lt;br /&gt;
All the &amp;quot;gen_[number]&amp;quot; entries up the tie io.ox/portal//generation will be used for this configuration. If a tile is deleted it is deleted only in that generation so can be reintroduced in a later portal configuration generation. If you want to keep the default tiles as used as a fallback for App Suite, you need this configuration to start out with:&lt;br /&gt;
&lt;br /&gt;
 io.ox/portal//widgets/eager/gen_0:&lt;br /&gt;
    mail_0: &lt;br /&gt;
        plugin: 'plugins/portal/mail/register'&lt;br /&gt;
        color: 'blue'&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: 1&lt;br /&gt;
    calendar_0: &lt;br /&gt;
        plugin: 'plugins/portal/calendar/register'&lt;br /&gt;
        color: 'red'&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: 2&lt;br /&gt;
    tasks_0: &lt;br /&gt;
        plugin: 'plugins/portal/tasks/register'&lt;br /&gt;
        color: 'green'&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: 3&lt;br /&gt;
    birthdays_0:&lt;br /&gt;
        plugin: 'plugins/portal/birthdays/register'&lt;br /&gt;
        color: 'lightgreen'&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: 4&lt;br /&gt;
    twitter_0:&lt;br /&gt;
        plugin: 'plugins/portal/twitter/register'&lt;br /&gt;
        color: 'pink'&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: 5&lt;br /&gt;
    linkedin_0:&lt;br /&gt;
        plugin: 'plugins/portal/linkedin/register'&lt;br /&gt;
        color: 'lightblue'&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: 6&lt;br /&gt;
    &lt;br /&gt;
And then modify this as wanted for your deployment. Note, that LikedIn support was removed with version 7.10.&lt;br /&gt;
&lt;br /&gt;
== Forcing a tile == &lt;br /&gt;
&lt;br /&gt;
Similarly to the eager tiles, tiles can be &amp;quot;protected&amp;quot;, i.e. they can not be moved, removed and disabled. The configuration for this looks like that:&lt;br /&gt;
&lt;br /&gt;
 io.ox/portal//widgets/protected:&lt;br /&gt;
    birthdays_0:&lt;br /&gt;
        color: &amp;quot;lightgreen&amp;quot;&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: &amp;quot;first&amp;quot;&lt;br /&gt;
        inverse: false&lt;br /&gt;
        plugin: &amp;quot;plugins/portal/birthdays/register&amp;quot;&lt;br /&gt;
        type: &amp;quot;birthdays&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you want to allow movement of the widget, you can enable this in the following way:&lt;br /&gt;
&lt;br /&gt;
 io.ox/portal//widgets/protected:&lt;br /&gt;
    birthdays_0:&lt;br /&gt;
        color: &amp;quot;lightgreen&amp;quot;&lt;br /&gt;
        enabled: true&lt;br /&gt;
        index: &amp;quot;first&amp;quot;&lt;br /&gt;
        inverse: false&lt;br /&gt;
        plugin: &amp;quot;plugins/portal/birthdays/register&amp;quot;&lt;br /&gt;
        type: &amp;quot;birthdays&amp;quot;&lt;br /&gt;
        changeable:&lt;br /&gt;
            index: true&lt;br /&gt;
&lt;br /&gt;
In which case, users will be allowed to move the tile. &lt;br /&gt;
&lt;br /&gt;
One caveat in all this: After changing any of the above configuration, you will have to reload the UI *twice*, since App Suite uses read-through caching for the settings data.&lt;br /&gt;
&lt;br /&gt;
== Disabling a tile completely ==&lt;br /&gt;
The combination of making a tile both protected and disabling it makes it impossible for the user to enable it. From 7.6.0 on, this means it is not shown in the settings either. Before that, it was greyed out but still present.&lt;br /&gt;
&lt;br /&gt;
 io.ox/portal/:&lt;br /&gt;
   widgets:&lt;br /&gt;
     protected:&lt;br /&gt;
       quota_0:&lt;br /&gt;
         color: &amp;quot;red&amp;quot;&lt;br /&gt;
         id: &amp;quot;quota_0&amp;quot;&lt;br /&gt;
         enabled: false&lt;br /&gt;
         index: 1&lt;br /&gt;
         inverse: false&lt;br /&gt;
         plugin: &amp;quot;plugins/portal/quota/register&amp;quot;&lt;br /&gt;
         type: &amp;quot;quota&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Category:Backend]][[Category:AppSuite]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Portal]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]][[Category:Developer]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Architecture_Overview&amp;diff=24054</id>
		<title>AppSuite:Architecture Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Architecture_Overview&amp;diff=24054"/>
		<updated>2018-06-20T05:53:18Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
This page gives an overview of the most important internal components, plugin capabilities, public interfaces (APIs) and data communication streams of the Open-Xchange server. &lt;br /&gt;
&lt;br /&gt;
[[File:appsuite_architecture_diagram_3.png|1200px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Frontend and client based communication flow                                 &amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''1''' All communication from and to the users client is purely based on HTTP. It is strongly recommended to use only encrypted HTTPS. For security reasons, some modules require HTTPS connections in the default configuration. The HTTP(S) communication is terminated at Apache.&lt;br /&gt;
&lt;br /&gt;
*'''2''' Within Apache, the mod_proxy_http module is used to forward the request to the OX server. Apache can also be used to configure session stickiness and load balancing in clustered environments.&lt;br /&gt;
&lt;br /&gt;
*'''3''' OX Web UI&lt;br /&gt;
** The [https://documentation.open-xchange.com/latest/middleware/http_api.html HTTP API] is the core API for all user functionality. Every function of the Web UI is using this API. In addition to that, all possible user functionality is available via this API and can be used from external applications as well. It is based on JSON via HTTP(S).&lt;br /&gt;
** [http://oxpedia.org/wiki/index.php?title=Portal:AppSuite_UI Web UI Documentation]&lt;br /&gt;
** [[HTTP_API_Examples|Programming Example]], how to use this API to build an Email widget, accessing the HTTP API&lt;br /&gt;
&lt;br /&gt;
*'''4''' The OXtender for Business Mobility is a server based Active Sync Implementation. The &amp;quot;Microsoft Exchange Active Sync&amp;quot; protocol supports Push via HTTPS, therefore the email backend needs to send push events to the OX server. Details, see: [[OXtender for Business Mobility Installation Guide]]  and [[OX_EMail_Push_Introduction|Email Push Introduction]]. Serverside, the synchronization makes use of the &amp;quot;Universal Sync Module (USM)&amp;quot;, which is a server bundle containing the synchronization logic for several clients. It also communicates via HTTP(S) transporting JSON objects.&lt;br /&gt;
&lt;br /&gt;
*'''5''' The [[OXtender 2 for Microsoft Outlook]] is a MAPI plugin, installed in the Outlook client to synchronize data between Outlook and the OX server. It makes use of the same HTTP(S) and JSON based communication to the Universal Sync Module (USM), like Active Sync.&lt;br /&gt;
&lt;br /&gt;
*'''6''' [[Caldav carddav Bundles|CalDAV and CardDAV]] interfaces are available to synchronize calendars and address books with Apple OS X and iOS applications as well as Thunderbird: [[CalDAVClients|CalDAV Clients]] and [[CardDAVClients|CardDAV Clients]].&lt;br /&gt;
&lt;br /&gt;
*'''7''' A WebDAV implementation provides the possibility to access the documents in the Files-module directly via any WebDAV client, like the Windows Explorer.&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Administration, provisioning and operations related components and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''11''' Data Migration and Im-/Export of user data can be done via automated tools, using these interfaces: &lt;br /&gt;
** [[Using the import servlet]], [[Building an importer]]&lt;br /&gt;
** [[Using the export servlet]], [[Building an exporter]], [[Export_ical/vcard| iCal/vCard]]&lt;br /&gt;
** A tool is available to upload data from Outlook profiles or PST files to OX: [http://oxpedia.org/wiki/index.php?title=OX_Outlook_Uploader Outlook Uploader]&lt;br /&gt;
&lt;br /&gt;
*'''12''' All provisioning tasks, like creating and editing users can be done with [[AppSuite:AdminGuide_7.8.4#OX_App_Suite_Management_.28CLT.29|Commandline tools]]. The command line tools make use of the Java RMI API internally.&lt;br /&gt;
&lt;br /&gt;
*'''13''' The native, central provisioning API is available via Java RMI and split into the [http://software.open-xchange.com/OX6/doc/RMI/admin-core/ Core API]  and the  [http://software.open-xchange.com/OX6/doc/RMI/admin-hosting/ HostingAPI].&lt;br /&gt;
&lt;br /&gt;
*'''14''' Central control panels and billing systems, which are not implemented in Java, can use the [[Open-Xchange-SOAP|SOAP API]].&lt;br /&gt;
** For OX as a Service, there's a specific [[OX_as_a_Service_Provisioning_using_SOAP|SOAP API documentation]]&lt;br /&gt;
&lt;br /&gt;
*'''15''' Authentication is implementable via highly customizable plugins, different standard and custom implementations are available&lt;br /&gt;
**[[Authentication IMAP Plugin description| IMAP]]&lt;br /&gt;
** LDAP&lt;br /&gt;
** Database&lt;br /&gt;
** custom&lt;br /&gt;
&lt;br /&gt;
*'''16''' Monitoring the OX application is done via JMX, for a description see [[OX monitoring interface]], or a commandline tool&lt;br /&gt;
** An example how to use the monitoring interface is available as pre-built Scripts for the monitoring tool Munin: [[OX munin scripts]]&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#E5E5E5&amp;quot;&amp;gt;Backend related components and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''21''' All OX-internal data - users, contacts, calendars, tasks and document metadata is stored in a MySQL Database, accessed via JDBC&lt;br /&gt;
**'''22''' Native MySQL contacts storage&lt;br /&gt;
&lt;br /&gt;
*'''23''' Other sources for contacts than the MySQL storage can also be used. For this an OSGi bundle needs to be implemented, overriding the standard contact storage.&lt;br /&gt;
** An implementation using LDAP is publicly available&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
*'''24''' Email storage is accessed through the pluggable [http://software.open-xchange.com/OX6/doc/mal/ Mail Abstraction Layer API] &lt;br /&gt;
** The default implementation uses IMAP&lt;br /&gt;
** Sending Emails is done via SMTP&lt;br /&gt;
** For Active Sync or Outlook the email backend needs to send push requests to the OX server, for details see [[OX_EMail_Push_Introduction|Email Push Introduction]]&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
*'''25''' Documents in the Files module are accessed via an API, which allows customized implementations.&lt;br /&gt;
** The default in large environments is to use NFS&lt;br /&gt;
** In small environments the local filesystem is used&lt;br /&gt;
** [http://www.scality.com/ Scality] is also available&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#E5E5E5&amp;quot;&amp;gt;Social/Public Data related components, plugins and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;em&amp;gt;subscription based plugin system&amp;lt;/em&amp;gt; allows to access data from external systems like webmail systems or social networks. The underlying concept is called SocialOX and a list of some plugins can be found here: [[SupportedCrawler]]. The integrations of messaging, contacts and calendars are done via the official API of the respective 3rd-party-service if there is one. For authentication, OAuth is used for security and privacy control if available. All plugins use HTTP(S) connections to the external services only. Access to the external email systems is done via IMAP(S) or POP3(S), depending on the service.&lt;br /&gt;
&lt;br /&gt;
*'''31''' For subscription to an external calendar a plugin to subscribe to Google Calendar is available.&lt;br /&gt;
&lt;br /&gt;
*'''32''' Supported external messaging services are Twitter and SMS/MMS.&lt;br /&gt;
&lt;br /&gt;
*'''33''' Contacts can be imported from Xing, LinkedIn (removed since 7.10.0), MSN/Windows Live/Outlook.com, Yahoo and Google.&lt;br /&gt;
&lt;br /&gt;
*'''34''' External email accounts can be integrated via POP3(S) or IMAP(S)&lt;br /&gt;
** There are pre-configured settings for many popular services so that users only need to enter their e-mail address and password.&lt;br /&gt;
** Look here how to [[install and configure the mail-account plugin]].&lt;br /&gt;
&lt;br /&gt;
* '''35''' RSS feeds are loaded remotely, filtered for exploits and can be read in the UI&lt;br /&gt;
&lt;br /&gt;
* '''36''' Image services like Flickr and Tumblr are integrated directly into the UI, bypassing the backend completely. Authentication is handled via OAuth.&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Publicly Available Plugins&amp;lt;/span&amp;gt;=&lt;br /&gt;
* An overview of the existing public plugins can be found here: [[Open-Xchange Plugin Overview]]. Many others are available on request or through partners.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=Open-Xchange_Plugin_Overview&amp;diff=23880</id>
		<title>Open-Xchange Plugin Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=Open-Xchange_Plugin_Overview&amp;diff=23880"/>
		<updated>2018-03-16T10:07:25Z</updated>

		<summary type="html">&lt;p&gt;Choeger: Redirected page to AppSuite:Open-Xchange Plugin Overview&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[AppSuite:Open-Xchange Plugin Overview]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Open-Xchange_Plugin_Overview&amp;diff=23878</id>
		<title>AppSuite:Open-Xchange Plugin Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Open-Xchange_Plugin_Overview&amp;diff=23878"/>
		<updated>2018-03-16T10:05:21Z</updated>

		<summary type="html">&lt;p&gt;Choeger: Choeger moved page OX6:Open-Xchange Plugin Overview to AppSuite:Open-Xchange Plugin Overview&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview of available Open-Xchange Plugins =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Core Plugins ==&lt;br /&gt;
&lt;br /&gt;
These plugins are part of the Open-Xchange Server Core platform.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
!style=&amp;quot;width:230px&amp;quot; align=&amp;quot;left&amp;quot; |Name&lt;br /&gt;
!style=&amp;quot;width:230px&amp;quot; align=&amp;quot;left&amp;quot; |Description&lt;br /&gt;
!align=&amp;quot;left&amp;quot; |Documentation&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-authentication-ldap]&lt;br /&gt;
|Authentication against LDAP server&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-authentication-imap]&lt;br /&gt;
|Authentication against IMAP server&lt;br /&gt;
|[[Authentication_IMAP_Plugin_description|Authentication imap plugin description]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-admin-plugin-contextrestore]&lt;br /&gt;
|Plugin to restore one or more contexts from a complete database dump&lt;br /&gt;
|http://software.open-xchange.com/OX6/doc/OX6-Installation-and-Administration.pdf&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-dataretention / open-xchange-dataretention-csv]&lt;br /&gt;
|Module to be used for data retention (german: Vorratsdatenspeicherung)&lt;br /&gt;
|open-xchange-dataretention-csv is an example implementation of the data retention service&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-commons-logging-log4j / open-xchange-log4j]&lt;br /&gt;
|These packages must be installed when Open-Xchange should use syslog&lt;br /&gt;
|[[Syslog_Configuration|Syslog configuration]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-contacts-ldap]&lt;br /&gt;
|Integrate LDAP address book into Open-Xchange public folder tree&lt;br /&gt;
|http://software.open-xchange.com/OX6/doc/OX6-Installation-and-Administration.pdf&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-subscribe-crawler]&lt;br /&gt;
|The open-xchange Social OX PlugIn bundle to subscribe/import data&lt;br /&gt;
|[[CrawlerArchitecture|Architecture of the Social OX PlugIn bundle]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-upsell-multiple]&lt;br /&gt;
|Implementing an up sell layer in Open-Xchange&lt;br /&gt;
|[[Upsell|Upsell package description]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-report-client]&lt;br /&gt;
|Tool to display and report the amount of users and contexts in the Open-Xchange environment&lt;br /&gt;
|[[OXReportClient|Report Client description]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/OXtender-stable/OXUpdater/ open-xchange-outlook-updater]&lt;br /&gt;
|Updater server bundle to download OXtender directly from Open-Xchange GUI&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-passwordchange-script]&lt;br /&gt;
|Use an external command to change a password&lt;br /&gt;
|[[ChangePasswordExternal|Example Script]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-publish-microformats]&lt;br /&gt;
|Publishing of Open-Xchange internal data structures like contacts, documents.&lt;br /&gt;
|[[Open-Xchange_Publishing|Publishing Data with Open-Xchange]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-calendar-printing]&lt;br /&gt;
|Generating printviews of calendar items&lt;br /&gt;
|[[Open-Xchange_Publishing|Publishing Data with Open-Xchange]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-audit]&lt;br /&gt;
|User action tracking bundle&lt;br /&gt;
|[[OXAudit|Audit bundle description]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-push-mailnotify]&lt;br /&gt;
|Accepting external new mail notifications&lt;br /&gt;
|[[MailNotify_Bundle|Mail Notification (Push) with Open-Xchange]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-push-imapidle]&lt;br /&gt;
|Mail push using IMAP IDLE&lt;br /&gt;
|[[MailPushIMAPIDLE_Bundle|Mail Notification (Push) with Open-Xchange]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-subscribe-msn]&lt;br /&gt;
|MSN subscription&lt;br /&gt;
|[[MSN_Bundles|Windows Live / MSN]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-messaging-twitter]&lt;br /&gt;
|Twitter messaging&lt;br /&gt;
|[[Twitter_Bundles|Twitter]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-subscribe-linkedin]&lt;br /&gt;
|LinkedIn subscription&lt;br /&gt;
|[[LinkedIn_Bundles|LinkedIn]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-admin-plugin-reseller]&lt;br /&gt;
|Reseller provisioning plugin&lt;br /&gt;
|[[Reseller_Bundle|Install the Open-Xchange Reseller package]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-caldav open-xchange-carddav open-xchange-webdav-acl open-xchange-webdav-directory]&lt;br /&gt;
|Bundles implementing CalDAV and CardDAV functionalities for Open-Xchange&lt;br /&gt;
|[[Caldav carddav Bundles|Using the CalDAV and CardDAV bundles]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://software.open-xchange.com/OX6/stable/ open-xchange-messaging-sms open-xchange-messaging-sms-gui open-xchange-messaging-sms-gui-theme-default]&lt;br /&gt;
|Bundles offering the SMS/MMS interfaces for Open-Xchange&lt;br /&gt;
|[[Custom_SMS_MMS_Implementation|Developing a SMS/MMS gateway implementation]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Additional Plugins ==&lt;br /&gt;
&lt;br /&gt;
The plugins listed here are not - yet - part of the Core platform and may or may not ever be part of the Open-Xchange Core platform.&lt;br /&gt;
&lt;br /&gt;
These plugins are not supported by Open-Xchange with the exception of concrete projects. Please [http://www.open-xchange.com/en/contactus contact us] for more details.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
!style=&amp;quot;width:230px&amp;quot; align=&amp;quot;left&amp;quot; |Name&lt;br /&gt;
!style=&amp;quot;width:230px&amp;quot; align=&amp;quot;left&amp;quot; |Description&lt;br /&gt;
!align=&amp;quot;left&amp;quot; |Documentation&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Custom Plugins ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following list consists of plugins, that Open-Xchange developed for specific customers. It is an overview of what is possible to do with the Open-Xchange integration platform.&lt;br /&gt;
&lt;br /&gt;
If you want Open-Xchange to develop a specific plugin for you, please [http://www.open-xchange.com/en/contactus contact us] for more details.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
!style=&amp;quot;width:150px&amp;quot; align=&amp;quot;left&amp;quot; |Name&lt;br /&gt;
!align=&amp;quot;left&amp;quot; |Description&lt;br /&gt;
|-&lt;br /&gt;
|MAL&lt;br /&gt;
|Plugin which replaces the standard imap/smtp plugin to access the mail store with a customer specific plugin, e.g. directly access a [http://en.wikipedia.org/wiki/Maildir maildir] mailstore.&lt;br /&gt;
|-&lt;br /&gt;
|Upsell&lt;br /&gt;
|If the example upsell plugin does not fit your needs or has some missing functionality, do not hesitate to contact us.&lt;br /&gt;
|-&lt;br /&gt;
|Spam&lt;br /&gt;
|It's possible to integrate the built in mark as SPAM/HAM functionality into almost any solution.&lt;br /&gt;
|-&lt;br /&gt;
|Authentication&lt;br /&gt;
|Authentication can be done against every system that allows to specify a username/password combination.&lt;br /&gt;
|-&lt;br /&gt;
|Migration from OX5 to OX6&lt;br /&gt;
|Migration plugin that updates the user passwords in OX6 Database after a successful login to the OX5 LDAP service. That way, passwords can be migrated automatically from any LDAP to OX6 database.&lt;br /&gt;
|-&lt;br /&gt;
|Corporate Integration: EasyLogin&lt;br /&gt;
|The EasyLogin mechanism allows to login into Open-Xchange from other applications without specifying username and password again.&lt;br /&gt;
|-&lt;br /&gt;
|Corporate Integration: ConfigJump&lt;br /&gt;
|Integrate your own configuration application in the Open-Xchange settings tree.&lt;br /&gt;
|-&lt;br /&gt;
|UI Customization&lt;br /&gt;
|A lot of customization can be done in the Open-Xchange UI. Starting from themes to the integration of custom modules and functions.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category: OX6]]&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Architecture_Overview&amp;diff=23877</id>
		<title>AppSuite:Architecture Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Architecture_Overview&amp;diff=23877"/>
		<updated>2018-03-16T09:15:49Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
This page gives an overview of the most important internal components, plugin capabilities, public interfaces (APIs) and data communication streams of the Open-Xchange server. &lt;br /&gt;
&lt;br /&gt;
[[File:appsuite_architecture_diagram_3.png|1200px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Frontend and client based communication flow                                 &amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''1''' All communication from and to the users client is purely based on HTTP. It is strongly recommended to use only encrypted HTTPS. For security reasons, some modules require HTTPS connections in the default configuration. The HTTP(S) communication is terminated at Apache.&lt;br /&gt;
&lt;br /&gt;
*'''2''' Within Apache, the mod_proxy_http module is used to forward the request to the OX server. Apache can also be used to configure session stickiness and load balancing in clustered environments.&lt;br /&gt;
&lt;br /&gt;
*'''3''' OX Web UI&lt;br /&gt;
** The [https://documentation.open-xchange.com/latest/middleware/http_api.html HTTP API] is the core API for all user functionality. Every function of the Web UI is using this API. In addition to that, all possible user functionality is available via this API and can be used from external applications as well. It is based on JSON via HTTP(S).&lt;br /&gt;
** [http://oxpedia.org/wiki/index.php?title=Portal:AppSuite_UI Web UI Documentation]&lt;br /&gt;
** [[HTTP_API_Examples|Programming Example]], how to use this API to build an Email widget, accessing the HTTP API&lt;br /&gt;
&lt;br /&gt;
*'''4''' The OXtender for Business Mobility is a server based Active Sync Implementation. The &amp;quot;Microsoft Exchange Active Sync&amp;quot; protocol supports Push via HTTPS, therefore the email backend needs to send push events to the OX server. Details, see: [[OXtender for Business Mobility Installation Guide]]  and [[OX_EMail_Push_Introduction|Email Push Introduction]]. Serverside, the synchronization makes use of the &amp;quot;Universal Sync Module (USM)&amp;quot;, which is a server bundle containing the synchronization logic for several clients. It also communicates via HTTP(S) transporting JSON objects.&lt;br /&gt;
&lt;br /&gt;
*'''5''' The [[OXtender 2 for Microsoft Outlook]] is a MAPI plugin, installed in the Outlook client to synchronize data between Outlook and the OX server. It makes use of the same HTTP(S) and JSON based communication to the Universal Sync Module (USM), like Active Sync.&lt;br /&gt;
&lt;br /&gt;
*'''6''' [[Caldav carddav Bundles|CalDAV and CardDAV]] interfaces are available to synchronize calendars and address books with Apple OS X and iOS applications as well as Thunderbird: [[CalDAVClients|CalDAV Clients]] and [[CardDAVClients|CardDAV Clients]].&lt;br /&gt;
&lt;br /&gt;
*'''7''' A WebDAV implementation provides the possibility to access the documents in the Files-module directly via any WebDAV client, like the Windows Explorer.&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Administration, provisioning and operations related components and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''11''' Data Migration and Im-/Export of user data can be done via automated tools, using these interfaces: &lt;br /&gt;
** [[Using the import servlet]], [[Building an importer]]&lt;br /&gt;
** [[Using the export servlet]], [[Building an exporter]], [[Export_ical/vcard| iCal/vCard]]&lt;br /&gt;
** A tool is available to upload data from Outlook profiles or PST files to OX: [http://oxpedia.org/wiki/index.php?title=OX_Outlook_Uploader Outlook Uploader]&lt;br /&gt;
&lt;br /&gt;
*'''12''' All provisioning tasks, like creating and editing users can be done with [http://software.open-xchange.com/OX6/doc/OX6-Provisioning/ Commandline tools]. The command line tools make use of the Java RMI API internally.&lt;br /&gt;
&lt;br /&gt;
*'''13''' The native, central provisioning API is available via Java RMI and split into the [http://software.open-xchange.com/OX6/doc/RMI/admin-core/ Core API]  and the  [http://software.open-xchange.com/OX6/doc/RMI/admin-hosting/ HostingAPI].&lt;br /&gt;
&lt;br /&gt;
*'''14''' Central control panels and billing systems, which are not implemented in Java, can use the [[Open-Xchange-SOAP|SOAP API]].&lt;br /&gt;
** For OX as a Service, there's a specific [[OX_as_a_Service_Provisioning_using_SOAP|SOAP API documentation]]&lt;br /&gt;
&lt;br /&gt;
*'''15''' Authentication is implementable via highly customizable plugins, different standard and custom implementations are available&lt;br /&gt;
**[[Authentication IMAP Plugin description| IMAP]]&lt;br /&gt;
** LDAP&lt;br /&gt;
** Database&lt;br /&gt;
** custom&lt;br /&gt;
&lt;br /&gt;
*'''16''' Monitoring the OX application is done via JMX, for a description see [[OX monitoring interface]], or a commandline tool&lt;br /&gt;
** An example how to use the monitoring interface is available as pre-built Scripts for the monitoring tool Munin: [[OX munin scripts]]&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#E5E5E5&amp;quot;&amp;gt;Backend related components and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''21''' All OX-internal data - users, contacts, calendars, tasks and document metadata is stored in a MySQL Database, accessed via JDBC&lt;br /&gt;
**'''22''' Native MySQL contacts storage&lt;br /&gt;
&lt;br /&gt;
*'''23''' Other sources for contacts than the MySQL storage can also be used. For this an OSGi bundle needs to be implemented, overriding the standard contact storage.&lt;br /&gt;
** An implementation using LDAP is publicly available&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
*'''24''' Email storage is accessed through the pluggable [http://software.open-xchange.com/OX6/doc/mal/ Mail Abstraction Layer API] &lt;br /&gt;
** The default implementation uses IMAP&lt;br /&gt;
** Sending Emails is done via SMTP&lt;br /&gt;
** For Active Sync or Outlook the email backend needs to send push requests to the OX server, for details see [[OX_EMail_Push_Introduction|Email Push Introduction]]&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
*'''25''' Documents in the Files module are accessed via an API, which allows customized implementations.&lt;br /&gt;
** The default in large environments is to use NFS&lt;br /&gt;
** In small environments the local filesystem is used&lt;br /&gt;
** [http://www.scality.com/ Scality] is also available&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#E5E5E5&amp;quot;&amp;gt;Social/Public Data related components, plugins and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;em&amp;gt;subscription based plugin system&amp;lt;/em&amp;gt; allows to access data from external systems like webmail systems or social networks. The underlying concept is called SocialOX and a list of some plugins can be found here: [[SupportedCrawler]]. The integrations of messaging, contacts and calendars are done via the official API of the respective 3rd-party-service if there is one. For authentication, OAuth is used for security and privacy control if available. All plugins use HTTP(S) connections to the external services only. Access to the external email systems is done via IMAP(S) or POP3(S), depending on the service.&lt;br /&gt;
&lt;br /&gt;
*'''31''' For subscription to an external calendar a plugin to subscribe to Google Calendar is available.&lt;br /&gt;
&lt;br /&gt;
*'''32''' Supported external messaging services are Twitter and SMS/MMS.&lt;br /&gt;
&lt;br /&gt;
*'''33''' Contacts can be imported from Xing, LinkedIn (removed since 7.10.0), MSN/Windows Live/Outlook.com, Yahoo and Google.&lt;br /&gt;
&lt;br /&gt;
*'''34''' External email accounts can be integrated via POP3(S) or IMAP(S)&lt;br /&gt;
** There are pre-configured settings for many popular services so that users only need to enter their e-mail address and password.&lt;br /&gt;
** Look here how to [[install and configure the mail-account plugin]].&lt;br /&gt;
&lt;br /&gt;
* '''35''' RSS feeds are loaded remotely, filtered for exploits and can be read in the UI&lt;br /&gt;
&lt;br /&gt;
* '''36''' Image services like Flickr and Tumblr are integrated directly into the UI, bypassing the backend completely. Authentication is handled via OAuth.&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Publicly Available Plugins&amp;lt;/span&amp;gt;=&lt;br /&gt;
* An overview of the existing public plugins can be found here: [[Open-Xchange Plugin Overview]]. Many others are available on request or through partners.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Architecture_Overview&amp;diff=23876</id>
		<title>AppSuite:Architecture Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:Architecture_Overview&amp;diff=23876"/>
		<updated>2018-03-16T08:59:19Z</updated>

		<summary type="html">&lt;p&gt;Choeger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
This page gives an overview of the most important internal components, plugin capabilities, public interfaces (APIs) and data communication streams of the Open-Xchange server. &lt;br /&gt;
&lt;br /&gt;
[[File:appsuite_architecture_diagram_3.png|1200px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Frontend and client based communication flow                                 &amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''1''' All communication from and to the users client is purely based on HTTP. It is strongly recommended to use only encrypted HTTPS. For security reasons, some modules require HTTPS connections in the default configuration. The HTTP(S) communication is terminated at Apache.&lt;br /&gt;
&lt;br /&gt;
*'''2''' Within Apache, the mod_proxy_http module is used to forward the request to the OX server. Apache can also be used to configure session stickiness and load balancing in clustered environments.&lt;br /&gt;
&lt;br /&gt;
*'''3''' OX Web UI&lt;br /&gt;
** The [https://documentation.open-xchange.com/latest/middleware/http_api.html HTTP API] is the core API for all user functionality. Every function of the Web UI is using this API. In addition to that, all possible user functionality is available via this API and can be used from external applications as well. It is based on JSON via HTTP(S).&lt;br /&gt;
** [http://oxpedia.org/wiki/index.php?title=Portal:AppSuite_UI Web UI Documentation]&lt;br /&gt;
** [[HTTP_API_Examples|Programming Example]], how to use this API to build an Email widget, accessing the HTTP API&lt;br /&gt;
&lt;br /&gt;
*'''4''' The OXtender for Business Mobility is a server based Active Sync Implementation. The &amp;quot;Microsoft Exchange Active Sync&amp;quot; protocol supports Push via HTTPS, therefore the email backend needs to send push events to the OX server. Details, see: [[OXtender for Business Mobility Installation Guide]]  and [[OX_EMail_Push_Introduction|Email Push Introduction]]. Serverside, the synchronization makes use of the &amp;quot;Universal Sync Module (USM)&amp;quot;, which is a server bundle containing the synchronization logic for several clients. It also communicates via HTTP(S) transporting JSON objects.&lt;br /&gt;
&lt;br /&gt;
*'''5''' The [[OXtender 2 for Microsoft Outlook]] is a MAPI plugin, installed in the Outlook client to synchronize data between Outlook and the OX server. It makes use of the same HTTP(S) and JSON based communication to the Universal Sync Module (USM), like Active Sync.&lt;br /&gt;
&lt;br /&gt;
*'''6''' [[Caldav carddav Bundles|CalDAV and CardDAV]] interfaces are available to synchronize calendars and address books with Apple OS X and iOS applications as well as Thunderbird: [[CalDAVClients|CalDAV Clients]] and [[CardDAVClients|CardDAV Clients]].&lt;br /&gt;
&lt;br /&gt;
*'''7''' A WebDAV implementation provides the possibility to access the documents in the Files-module directly via any WebDAV client, like the Windows Explorer.&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Administration, provisioning and operations related components and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''11''' Data Migration and Im-/Export of user data can be done via automated tools, using these interfaces: &lt;br /&gt;
** [[Using the import servlet]], [[Building an importer]]&lt;br /&gt;
** [[Using the export servlet]], [[Building an exporter]], [[Export_ical/vcard| iCal/vCard]]&lt;br /&gt;
** A tool is available to upload data from Outlook profiles or PST files to OX: [http://oxpedia.org/wiki/index.php?title=OX_Outlook_Uploader Outlook Uploader]&lt;br /&gt;
&lt;br /&gt;
*'''12''' All provisioning tasks, like creating and editing users can be done with [http://software.open-xchange.com/OX6/doc/OX6-Provisioning/ Commandline tools]. The command line tools make use of the Java RMI API internally.&lt;br /&gt;
&lt;br /&gt;
*'''13''' The native, central provisioning API is available via Java RMI and split into the [http://software.open-xchange.com/OX6/doc/RMI/admin-core/ Core API]  and the  [http://software.open-xchange.com/OX6/doc/RMI/admin-hosting/ HostingAPI].&lt;br /&gt;
&lt;br /&gt;
*'''14''' Central control panels and billing systems, which are not implemented in Java, can use the RMI API via the [http://software.open-xchange.com/products/appsuite/doc/SOAP/admin/OX-Admin-SOAP.html SOAP API], examples of its usage can be found [[Open-Xchange-SOAP | here]].&lt;br /&gt;
** Standard integration via SOAP is available for OPWV Directory&lt;br /&gt;
** for Parallels Operations Automation see [[PAIntegrationGuide| PA integration guide]]&lt;br /&gt;
** for Parallels Plesk Panel see [[Plesk_Integration|Plesk integration guide]]&lt;br /&gt;
** for cPanel see [[Open-Xchange_cPanel_Installation| cPanel installation]]&lt;br /&gt;
&lt;br /&gt;
*'''15''' Authentication is implementable via highly customizable plugins, different standard and custom implementations are available&lt;br /&gt;
**[[Authentication IMAP Plugin description| IMAP]]&lt;br /&gt;
** LDAP&lt;br /&gt;
** Database&lt;br /&gt;
** custom&lt;br /&gt;
&lt;br /&gt;
*'''16''' Monitoring the OX application is done via JMX, for a description see [[OX monitoring interface]], or a commandline tool&lt;br /&gt;
** An example how to use the monitoring interface is available as pre-built Scripts for the monitoring tool Munin: [[OX munin scripts]]&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#E5E5E5&amp;quot;&amp;gt;Backend related components and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
*'''21''' All OX-internal data - users, contacts, calendars, tasks and document metadata is stored in a MySQL Database, accessed via JDBC&lt;br /&gt;
**'''22''' Native MySQL contacts storage&lt;br /&gt;
&lt;br /&gt;
*'''23''' Other sources for contacts than the MySQL storage can also be used. For this an OSGi bundle needs to be implemented, overriding the standard contact storage.&lt;br /&gt;
** An implementation using LDAP is publicly available&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
*'''24''' Email storage is accessed through the pluggable [http://software.open-xchange.com/OX6/doc/mal/ Mail Abstraction Layer API] &lt;br /&gt;
** The default implementation uses IMAP&lt;br /&gt;
** Sending Emails is done via SMTP&lt;br /&gt;
** For Active Sync or Outlook the email backend needs to send push requests to the OX server, for details see [[OX_EMail_Push_Introduction|Email Push Introduction]]&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
*'''25''' Documents in the Files module are accessed via an API, which allows customized implementations.&lt;br /&gt;
** The default in large environments is to use NFS&lt;br /&gt;
** In small environments the local filesystem is used&lt;br /&gt;
** [http://www.scality.com/ Scality] is also available&lt;br /&gt;
** Several custom implementations are available on request or can be implemented by partners&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#E5E5E5&amp;quot;&amp;gt;Social/Public Data related components, plugins and communication flow&amp;lt;/span&amp;gt;=&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;em&amp;gt;subscription based plugin system&amp;lt;/em&amp;gt; allows to access data from external systems like webmail systems or social networks. The underlying concept is called SocialOX and a list of some plugins can be found here: [[SupportedCrawler]]. The integrations of messaging, contacts and calendars are done via the official API of the respective 3rd-party-service if there is one. For authentication, OAuth is used for security and privacy control if available. All plugins use HTTP(S) connections to the external services only. Access to the external email systems is done via IMAP(S) or POP3(S), depending on the service.&lt;br /&gt;
&lt;br /&gt;
*'''31''' For subscription to an external calendar a plugin to subscribe to Google Calendar is available.&lt;br /&gt;
&lt;br /&gt;
*'''32''' Supported external messaging services are Twitter and SMS/MMS.&lt;br /&gt;
&lt;br /&gt;
*'''33''' Contacts can be imported from Xing, LinkedIn (removed since 7.10.0), MSN/Windows Live/Outlook.com, Yahoo and Google.&lt;br /&gt;
&lt;br /&gt;
*'''34''' External email accounts can be integrated via POP3(S) or IMAP(S)&lt;br /&gt;
** There are pre-configured settings for many popular services so that users only need to enter their e-mail address and password.&lt;br /&gt;
** Look here how to [[install and configure the mail-account plugin]].&lt;br /&gt;
&lt;br /&gt;
* '''35''' RSS feeds are loaded remotely, filtered for exploits and can be read in the UI&lt;br /&gt;
&lt;br /&gt;
* '''36''' Image services like Flickr and Tumblr are integrated directly into the UI, bypassing the backend completely. Authentication is handled via OAuth.&lt;br /&gt;
&lt;br /&gt;
=&amp;lt;span style=&amp;quot;background:#dcdcdc&amp;quot;&amp;gt;Publicly Available Plugins&amp;lt;/span&amp;gt;=&lt;br /&gt;
* An overview of the existing public plugins can be found here: [[Open-Xchange Plugin Overview]]. Many others are available on request or through partners.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=Clustercheck&amp;diff=23739</id>
		<title>Clustercheck</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=Clustercheck&amp;diff=23739"/>
		<updated>2017-11-08T10:04:34Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* HAproxy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Custom clustercheck for Galera cluster =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
When using [[OXLoadBalancingClustering_Database#Galera_database_setup|Galera]] as clustered MySQL database for OX App Suite, a loadbalancer is required to ''transform'' Galera's notion of ''equivalent'' cluster nodes into OX's understanding of ''master'' and ''slave'' nodes (or &amp;lt;code&amp;gt;writeUrl&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;readUrl&amp;lt;/code&amp;gt;). Typical choice is a round-robin fashion for the &amp;lt;code&amp;gt;readUrl&amp;lt;/code&amp;gt; and a persistent active-passive behavior for the &amp;lt;code&amp;gt;writeUrl&amp;lt;/code&amp;gt;. See [[OXLoadBalancingClustering_Database#Notes_about_configuring_OX_for_use_with_Galera|the Galera setup page]] for more detailed information.&lt;br /&gt;
&lt;br /&gt;
The loadbalancers need to be able to check the health status of the Galera cluster nodes in order to decide which nodes are available for read requests, and which node should be picked persistently for write requestes. The latter point is most important if we are considering a lot of ''distributed'' loadbalancers not synchronizing their target list with each other, as one of our proposed high level design options works (distributed HAproxy instances on the OX App Suite groupware nodes). It seems natural to leverage the mechanism also used by [[Maxscale|MariaDB Maxscale]] to define a ''master'' node: use the one with &amp;lt;code&amp;gt;wsrep_local_index=0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Recent versions of the packages (both MariaDB and Percona) ship with a &amp;lt;code&amp;gt;/usr/bin/clustercheck&amp;lt;/code&amp;gt; script which has basically been designed for that task. However, the original version has some shortcomings, most noticeably it has been designed for and works only with HAproxy, but not with Keepalived; and it offers no support for the &amp;lt;code&amp;gt;wsrep_local_index=0&amp;lt;/code&amp;gt; feature discussed above. So, we decided to improve on that script.&lt;br /&gt;
&lt;br /&gt;
== Basic Installation and Testing ==&lt;br /&gt;
&lt;br /&gt;
Copy-paste the script pasted below in a location on your Galera nodes where it will not be overwritten. We assume &amp;lt;code&amp;gt;/usr/local/bin/clustercheck&amp;lt;/code&amp;gt; for that purpose.&lt;br /&gt;
&lt;br /&gt;
The script needs a user like&lt;br /&gt;
&lt;br /&gt;
 GRANT PROCESS ON *.* TO 'clustercheck'@'localhost' IDENTIFIED BY '3shyShynhut';&lt;br /&gt;
&lt;br /&gt;
Make the script it executable and test:&lt;br /&gt;
&lt;br /&gt;
 # echo &amp;quot;GET / HTTP/1.0&amp;quot; | /usr/local/bin/clustercheck clustercheck 3shyShynhut&lt;br /&gt;
 HTTP/1.0 200 OK&lt;br /&gt;
 Content-Length: 40&lt;br /&gt;
 &lt;br /&gt;
 Percona XtraDB Cluster Node is synced.&lt;br /&gt;
&lt;br /&gt;
Note 1: The arguments in that sample call are the MySQL user and password. We will change the way this is wired later.&lt;br /&gt;
&lt;br /&gt;
Note 2: The &amp;lt;code&amp;gt;echo &amp;quot;GET / HTTP/1.0&amp;quot;&amp;lt;/code&amp;gt; is actually kind of optional, but be aware that the script expects a (HTTP 1.0) request on standard input. That behavior is a change to the original &amp;lt;code&amp;gt;clustercheck&amp;lt;/code&amp;gt; script, but required for Keepalived, while still being compatible to HAproxy. So you could actually test also just by using &amp;lt;code&amp;gt;echo &amp;quot;&amp;quot; | ...&amp;lt;/code&amp;gt;. But you can change the behavior of the script by the URL passed, in particular by passing the URL &amp;lt;code&amp;gt;/master&amp;lt;/code&amp;gt; you can test for &amp;lt;code&amp;gt;wsrep_local_index==0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 # echo &amp;quot;GET /master HTTP/1.0&amp;quot; | /usr/local/bin/clustercheck clustercheck 3shyShynhut&lt;br /&gt;
 HTTP/1.0 200 OK&lt;br /&gt;
 Content-Length: 65&lt;br /&gt;
 &lt;br /&gt;
 Percona XtraDB Cluster Node is synced and wsrep_local_index==0.&lt;br /&gt;
&lt;br /&gt;
Or:&lt;br /&gt;
&lt;br /&gt;
 # echo &amp;quot;GET /master HTTP/1.0&amp;quot; | /usr/local/bin/clustercheck clustercheck 3shyShynhut&lt;br /&gt;
 HTTP/1.0 503 Service Unavailable&lt;br /&gt;
 Content-Length: 88&lt;br /&gt;
 &lt;br /&gt;
 Percona XtraDB Cluster Node is not wsrep_local_index==0 and you requested master mode.&lt;br /&gt;
&lt;br /&gt;
We actually recommend for security to configure some extra MySQL config file for the credentials like&lt;br /&gt;
&lt;br /&gt;
 # /usr/local/etc/clustercheck.my.cnf&lt;br /&gt;
 [client]&lt;br /&gt;
 user=clustercheck&lt;br /&gt;
 password=3shyShynhut&lt;br /&gt;
&lt;br /&gt;
Invocation then goes like&lt;br /&gt;
&lt;br /&gt;
 # echo &amp;quot;GET /master HTTP/1.0&amp;quot; | /usr/local/bin/clustercheck -f /usr/local/etc/clustercheck.my.cnf&lt;br /&gt;
&lt;br /&gt;
For further options see the script's usage info or the source code below. We want to emphasise and recommend something like&lt;br /&gt;
&lt;br /&gt;
 -e /var/log/clustercheck.log&lt;br /&gt;
&lt;br /&gt;
to have logging e.g. to &amp;lt;code&amp;gt;/var/log/clustercheck.log&amp;lt;/code&amp;gt;. Logging is disabled by default, like in the original script.&lt;br /&gt;
&lt;br /&gt;
Furthermore you want to think about and decide whether to use&lt;br /&gt;
&lt;br /&gt;
 -d&lt;br /&gt;
     Consider this node as available while being donor for a SST.&lt;br /&gt;
     Default: Donor node is considered unvailable.&lt;br /&gt;
 &lt;br /&gt;
 -r&lt;br /&gt;
     Consider this node as unavailable while being read-only.&lt;br /&gt;
     Default: read-only node is considered available.&lt;br /&gt;
&lt;br /&gt;
Our scripts behaves by default like the original one.&lt;br /&gt;
&lt;br /&gt;
Finally master mode can not only by toggled by the request path (see above), but also by a command line parameter.&lt;br /&gt;
&lt;br /&gt;
 -m&lt;br /&gt;
     Consider this as available only if it has got wsrep_local_index=0.&lt;br /&gt;
&lt;br /&gt;
== Installation as web service via xinetd ==&lt;br /&gt;
&lt;br /&gt;
Some of the different upstream packages install a &amp;lt;code&amp;gt;xinetd&amp;lt;/code&amp;gt; service definition file &amp;lt;code&amp;gt;/etc/xinetd.d/mysqlchk&amp;lt;/code&amp;gt;. If you don't have one, install the one pasted below. We use / configure it for our custom service like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# default: on&lt;br /&gt;
# description: mysqlchk&lt;br /&gt;
service mysqlchk&lt;br /&gt;
{&lt;br /&gt;
# this is a config for xinetd, place it in /etc/xinetd.d/&lt;br /&gt;
        disable = no&lt;br /&gt;
        flags           = REUSE&lt;br /&gt;
        socket_type     = stream&lt;br /&gt;
        type            = UNLISTED&lt;br /&gt;
        port            = 9200&lt;br /&gt;
        wait            = no&lt;br /&gt;
        user            = nobody&lt;br /&gt;
        server          = /usr/local/bin/clustercheck&lt;br /&gt;
        server_args     = -e /var/log/clustercheck.log -f /usr/local/etc/clustercheck.my.cnf&lt;br /&gt;
        log_on_failure  += USERID&lt;br /&gt;
        only_from       = 0.0.0.0/0&lt;br /&gt;
&lt;br /&gt;
        # recommended to put the IPs that need&lt;br /&gt;
        # to connect exclusively (security purposes)&lt;br /&gt;
        per_source      = UNLIMITED&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to&lt;br /&gt;
&lt;br /&gt;
 touch /var/log/clustercheck.log&lt;br /&gt;
 chown nobody /var/log/clustercheck.log&lt;br /&gt;
&lt;br /&gt;
So with the usual steps (&amp;lt;code&amp;gt;apt-get install xinetd; service xinetd restart&amp;lt;/code&amp;gt;, etc) we have a webservice for our clustercheck script.&lt;br /&gt;
&lt;br /&gt;
'''Note''': Please ensure that you haven't set the &amp;lt;code&amp;gt;max_load&amp;lt;/code&amp;gt; parameter in the xinetd configuration. This parameter will lead to &amp;lt;code&amp;gt;xinetd&amp;lt;/code&amp;gt; not answering any request if the load increases above this value. So the system will be detected dead even though it actually isn't.&lt;br /&gt;
&lt;br /&gt;
Final thing to do is to test this from the loadbalancer node (and adjust firewall configuration or whatever, if required).&lt;br /&gt;
&lt;br /&gt;
 # '''telnet db1 9200'''&lt;br /&gt;
 Trying 10.0.0.1...&lt;br /&gt;
 Connected to db1.&lt;br /&gt;
 Escape character is '^]'.&lt;br /&gt;
 '''GET / HTTP/1.0'''&lt;br /&gt;
 &lt;br /&gt;
 HTTP/1.0 200 OK&lt;br /&gt;
 Content-Length: 40&lt;br /&gt;
 &lt;br /&gt;
 Percona XtraDB Cluster Node is synced.&lt;br /&gt;
 Connection closed by foreign host.&lt;br /&gt;
&lt;br /&gt;
== Loadbalancer configuration ==&lt;br /&gt;
&lt;br /&gt;
=== HAproxy ===&lt;br /&gt;
&lt;br /&gt;
The service can be configured for use with [[HAproxy]]. See the [[HAproxy#Configuration|configuration]] page for details.&lt;br /&gt;
&lt;br /&gt;
=== Keepalived ===&lt;br /&gt;
&lt;br /&gt;
The service can also be configured for use with [[Keepalived]]. See the the [[Keepalived#Keepalived_configuration_.28with_health_checks.29|Keepalived]] page for more information.&lt;br /&gt;
&lt;br /&gt;
== The custom clustercheck script ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/bash&lt;br /&gt;
#&lt;br /&gt;
# Script to make a proxy (ie HAProxy) capable of monitoring Percona XtraDB Cluster nodes properly&lt;br /&gt;
#&lt;br /&gt;
# Authors:&lt;br /&gt;
# Raghavendra Prabhu &amp;lt;raghavendra.prabhu@percona.com&amp;gt;&lt;br /&gt;
# Olaf van Zandwijk &amp;lt;olaf.vanzandwijk@nedap.com&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Based on the original script from Unai Rodriguez and Olaf (https://github.com/olafz/percona-clustercheck)&lt;br /&gt;
#&lt;br /&gt;
# Heavily rewritten and extended by Dominik Epple &amp;lt;dominik.epple@open-xchange.com&amp;gt; 2017-09&lt;br /&gt;
#&lt;br /&gt;
# Grant privileges required:&lt;br /&gt;
# GRANT PROCESS ON *.* TO 'clustercheck'@'localhost' IDENTIFIED BY '3shyShynhut';&lt;br /&gt;
#&lt;br /&gt;
# Sample usage:&lt;br /&gt;
# # echo &amp;quot;GET / HTTP/1.0&amp;quot; | /usr/local/bin/clustercheck clustercheck 3shyShynhut&lt;br /&gt;
# HTTP/1.0 200 OK&lt;br /&gt;
# Content-Length: 40&lt;br /&gt;
# &lt;br /&gt;
# Percona XtraDB Cluster Node is synced.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
AVAILABLE_WHEN_DONOR=0&lt;br /&gt;
ERR_FILE=/dev/null&lt;br /&gt;
AVAILABLE_WHEN_READONLY=1&lt;br /&gt;
DEFAULTS_EXTRA_FILE=&amp;quot;&amp;quot;&lt;br /&gt;
DEFAULTS_FILE=&amp;quot;&amp;quot;&lt;br /&gt;
#Timeout exists for instances where mysqld may be hung&lt;br /&gt;
TIMEOUT=10&lt;br /&gt;
MASTER_MODE=0&lt;br /&gt;
&lt;br /&gt;
usage() {&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
usage:&lt;br /&gt;
    $0 [-h]&lt;br /&gt;
         show this usage text&lt;br /&gt;
&lt;br /&gt;
    $0 [-e error_file] [-f defaults_file] [-F defaults_extra_file] [-t timeout_secs] [-d] [-r] [-m] [user [pass]]&lt;br /&gt;
         Perform clustercheck. Arguments are&lt;br /&gt;
&lt;br /&gt;
             -e error_file&lt;br /&gt;
                 File to log errors to. Default: /dev/null&lt;br /&gt;
&lt;br /&gt;
             -f defaults_file&lt;br /&gt;
                 Defaults file for MySQL client. Default: none&lt;br /&gt;
                 Preferred way to pass credentials to the MySQL client.&lt;br /&gt;
&lt;br /&gt;
             -F defaults_extra_file&lt;br /&gt;
                 Extra defaults file for MySQL client. Default: none&lt;br /&gt;
                 Kept for compatibilty to original clustercheck.&lt;br /&gt;
&lt;br /&gt;
             -t timeout&lt;br /&gt;
                 Timeout for the MySQL client in seconds. Default: 10&lt;br /&gt;
&lt;br /&gt;
             -d&lt;br /&gt;
                 Consider this node as available while being donor for a SST. Default: Donor node is considered unvailable.&lt;br /&gt;
&lt;br /&gt;
             -r&lt;br /&gt;
                 Consider this node as unavailable while being read-only. Default: read-only node is considered available.&lt;br /&gt;
&lt;br /&gt;
             -m&lt;br /&gt;
                 Consider this as available only if it has got wsrep_local_index=0. Useful to define a &amp;quot;master&amp;quot; node.  You can also toggle MASTER_MODE by using the request path &amp;quot;/master&amp;quot;. Default: It is sufficient to be &amp;quot;Synced&amp;quot; for a node to be considered available.&lt;br /&gt;
&lt;br /&gt;
             user, pass&lt;br /&gt;
                 Credentials to connect to MySQL server to&lt;br /&gt;
&lt;br /&gt;
EOF&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
log_debug() {&lt;br /&gt;
    if [[ &amp;quot;$ERR_FILE&amp;quot; != &amp;quot;/dev/null&amp;quot; ]]; then&lt;br /&gt;
        # the following woulde give nanoseconds timestamps, but create extra processes, which I want to avoid in normal ops&lt;br /&gt;
        #echo &amp;quot;$(date --iso-8601=ns) $message&amp;quot; &amp;gt;&amp;gt; ${ERR_FILE}&lt;br /&gt;
        printf &amp;quot;%(%FT%T%z)T&amp;quot; -1 &amp;gt;&amp;gt; ${ERR_FILE}&lt;br /&gt;
        echo &amp;quot; $1&amp;quot; &amp;gt;&amp;gt; ${ERR_FILE}&lt;br /&gt;
    fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
output() {&lt;br /&gt;
    http_status=$1&lt;br /&gt;
    message=&amp;quot;$2&amp;quot;&lt;br /&gt;
    exit_status=$3&lt;br /&gt;
&lt;br /&gt;
    log_debug &amp;quot;sending \&amp;quot;$http_status\&amp;quot; \&amp;quot;$message\&amp;quot; to the client.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    length=${#message}&lt;br /&gt;
    length=$(( length + 2 ))&lt;br /&gt;
&lt;br /&gt;
    echo -en &amp;quot;HTTP/1.0 $http_status\r\n&amp;quot;&lt;br /&gt;
    echo -en &amp;quot;Content-Length: $length\r\n&amp;quot;&lt;br /&gt;
    echo -en &amp;quot;\r\n&amp;quot;&lt;br /&gt;
    echo -en &amp;quot;$message\r\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    1&amp;lt;&amp;amp;-&lt;br /&gt;
    exit $exit_status&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
while getopts &amp;quot;e:drf:t:mh&amp;quot; o; do&lt;br /&gt;
    case &amp;quot;${o}&amp;quot; in&lt;br /&gt;
        e)&lt;br /&gt;
            ERR_FILE=${OPTARG}&lt;br /&gt;
            ;;&lt;br /&gt;
        d)&lt;br /&gt;
            AVAILABLE_WHEN_DONOR=1&lt;br /&gt;
            ;;&lt;br /&gt;
        r)&lt;br /&gt;
            AVAILABLE_WHEN_READONLY=0&lt;br /&gt;
            ;;&lt;br /&gt;
        f)&lt;br /&gt;
            DEFAULTS_FILE=${OPTARG}&lt;br /&gt;
            ;;&lt;br /&gt;
        F)&lt;br /&gt;
            DEFAULTS_EXTRA_FILE=${OPTARG}&lt;br /&gt;
            ;;&lt;br /&gt;
        t)&lt;br /&gt;
            TIMEOUT=${OPTARG}&lt;br /&gt;
            ;;&lt;br /&gt;
        m)&lt;br /&gt;
            MASTER_MODE=1&lt;br /&gt;
            ;;&lt;br /&gt;
        h)&lt;br /&gt;
            usage&lt;br /&gt;
            exit 0&lt;br /&gt;
            ;;&lt;br /&gt;
        *)&lt;br /&gt;
            usage&lt;br /&gt;
            exit 1&lt;br /&gt;
            ;;&lt;br /&gt;
    esac&lt;br /&gt;
done&lt;br /&gt;
shift $((OPTIND-1))&lt;br /&gt;
&lt;br /&gt;
MYSQL_USERNAME=&amp;quot;${1}&amp;quot;&lt;br /&gt;
MYSQL_PASSWORD=&amp;quot;${2}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
EXTRA_ARGS=&amp;quot;--connect-timeout=$TIMEOUT -B -N&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [[ -n &amp;quot;$MYSQL_USERNAME&amp;quot; ]]; then&lt;br /&gt;
    EXTRA_ARGS=&amp;quot;$EXTRA_ARGS --user=${MYSQL_USERNAME}&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [[ -n &amp;quot;$MYSQL_PASSWORD&amp;quot; ]]; then&lt;br /&gt;
    EXTRA_ARGS=&amp;quot;$EXTRA_ARGS --password=${MYSQL_PASSWORD}&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [[ -n &amp;quot;$DEFAULTS_FILE&amp;quot; ]]; then&lt;br /&gt;
    if [[ -r &amp;quot;$DEFAULTS_FILE&amp;quot; ]]; then&lt;br /&gt;
        # seems like it must be the first agrument&lt;br /&gt;
        EXTRA_ARGS=&amp;quot;--defaults-file=$DEFAULTS_FILE $EXTRA_ARGS &amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;$0: error: defaults file $DEFAULTS_FILE not readable.&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [[ -n &amp;quot;$DEFAULTS_EXTRA_FILE&amp;quot; ]]; then&lt;br /&gt;
    if [[ -r &amp;quot;$DEFAULTS_EXTRA_FILE&amp;quot; ]]; then&lt;br /&gt;
        # seems like it must be the first agrument&lt;br /&gt;
        EXTRA_ARGS=&amp;quot;--defaults-extra-file=$DEFAULTS_EXTRA_FILE $EXTRA_ARGS &amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;$0: error: defaults extra file $DEFAULTS_EXTRA_FILE not readable.&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
MYSQL_CMDLINE=&amp;quot;mysql ${EXTRA_ARGS}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# irrelevant for haproxy, required for keepalived: try to read input&lt;br /&gt;
log_debug &amp;quot;Reading HTTP request ...&amp;quot;&lt;br /&gt;
while read line&lt;br /&gt;
do&lt;br /&gt;
    # https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable&lt;br /&gt;
    # remove trailing control characters&lt;br /&gt;
    # inner expression: truncate left everything until to the right only spaces are left -&amp;gt; is only right spaces&lt;br /&gt;
    # outer expression: truncate to the right the &amp;quot;right spaces&amp;quot;&lt;br /&gt;
    line=&amp;quot;${line%&amp;quot;${line##*[![:cntrl:]]}&amp;quot;}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    log_debug &amp;quot;Client sent: \&amp;quot;===$line===\&amp;quot;&amp;quot;&lt;br /&gt;
    if [[ -z &amp;quot;$line&amp;quot; ]]; then&lt;br /&gt;
        log_debug &amp;quot;Client sent empty line, breaking&amp;quot;&lt;br /&gt;
        break&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    set -- $line&lt;br /&gt;
    # haproxy sends by default OPTIONS, keepalived sends GET&lt;br /&gt;
    if [[ ${1,,} = &amp;quot;get&amp;quot; || ${1,,} = &amp;quot;options&amp;quot; ]]; then&lt;br /&gt;
        if [[ ${2:0:7} = &amp;quot;/master&amp;quot; ]]; then&lt;br /&gt;
            log_debug &amp;quot;Upgrading to master mode as requrested by /master URL.&amp;quot;&lt;br /&gt;
            MASTER_MODE=1&lt;br /&gt;
        fi&lt;br /&gt;
    fi&lt;br /&gt;
done&lt;br /&gt;
log_debug &amp;quot;Done reading HTTP request.&amp;quot;&lt;br /&gt;
set --&lt;br /&gt;
&lt;br /&gt;
log_debug &amp;quot;Calling MySQL...&amp;quot;&lt;br /&gt;
mysql_output=$($MYSQL_CMDLINE -e 'SHOW GLOBAL STATUS WHERE Variable_name REGEXP &amp;quot;^(wsrep_local_state|wsrep_cluster_status|wsrep_local_index)$&amp;quot;; show global variables like &amp;quot;read_only&amp;quot;;' 2&amp;gt;&amp;gt;${ERR_FILE} )&lt;br /&gt;
log_debug &amp;quot;MySQL output: ===$mysql_output===&amp;quot;&lt;br /&gt;
&lt;br /&gt;
set -- $mysql_output&lt;br /&gt;
while [[ $# -gt 1 ]]&lt;br /&gt;
do&lt;br /&gt;
    case &amp;quot;$1&amp;quot; in&lt;br /&gt;
    wsrep_local_state|wsrep_cluster_status|wsrep_local_index|read_only)&lt;br /&gt;
        declare $1=&amp;quot;$2&amp;quot;&lt;br /&gt;
        shift&lt;br /&gt;
        shift&lt;br /&gt;
        ;;&lt;br /&gt;
    *)&lt;br /&gt;
        log_debug &amp;quot;unexpected output from MySQL: $1 $2&amp;quot;&lt;br /&gt;
        shift&lt;br /&gt;
        shift&lt;br /&gt;
        ;;&lt;br /&gt;
    esac&lt;br /&gt;
done&lt;br /&gt;
log_debug &amp;quot;After parsing: wsrep_local_state=$wsrep_local_state wsrep_cluster_status=$wsrep_cluster_status wsrep_local_index=$wsrep_local_index read_only=$read_only&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [[ &amp;quot;$wsrep_cluster_status&amp;quot; == 'Primary' &amp;amp;&amp;amp; ( $wsrep_local_state -eq 4 || ( $wsrep_local_state -eq 2 &amp;amp;&amp;amp; $AVAILABLE_WHEN_DONOR -eq 1 ) ) ]]&lt;br /&gt;
then&lt;br /&gt;
    if [[ &amp;quot;${MASTER_MODE}&amp;quot; == 1 ]];then&lt;br /&gt;
        if [[ ${wsrep_local_index} -eq 0 ]];then&lt;br /&gt;
            output &amp;quot;200 OK&amp;quot; &amp;quot;Percona XtraDB Cluster Node is synced and wsrep_local_index==0.&amp;quot; 0&lt;br /&gt;
        else&lt;br /&gt;
            output &amp;quot;503 Service Unavailable&amp;quot; &amp;quot;Percona XtraDB Cluster Node is not wsrep_local_index==0 and you requested master mode.&amp;quot; 1&lt;br /&gt;
        fi&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    if [[ &amp;quot;${read_only}&amp;quot; == &amp;quot;ON&amp;quot; &amp;amp;&amp;amp; $AVAILABLE_WHEN_READONLY -eq 0 ]];then&lt;br /&gt;
        output &amp;quot;503 Service Unavailable&amp;quot; &amp;quot;Percona XtraDB Cluster Node is read_only and you requested AVAILABLE_WHEN_READONLY=0.&amp;quot; 1&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    output &amp;quot;200 OK&amp;quot; &amp;quot;Percona XtraDB Cluster Node is synced.&amp;quot; 0&lt;br /&gt;
else&lt;br /&gt;
    output &amp;quot;503 Service Unavailable&amp;quot; &amp;quot;Percona XtraDB Cluster Node is not synced or non-PRIM.&amp;quot; 1&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
	<entry>
		<id>https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:GuardCustomization&amp;diff=23624</id>
		<title>AppSuite:GuardCustomization</title>
		<link rel="alternate" type="text/html" href="https://wiki.open-xchange.com/wiki/index.php?title=AppSuite:GuardCustomization&amp;diff=23624"/>
		<updated>2017-08-31T07:20:20Z</updated>

		<summary type="html">&lt;p&gt;Choeger: /* Emails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Ox Guard Customization =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Guard uses several templates for emails and the Guest reader.  These templates are fully customizable, and can be customized at the global level, but also at the context/user level.  Changing images, colors, and layout is easy.  Changing the wording is also possible, though the translation tables will then need to be updated.&lt;br /&gt;
&lt;br /&gt;
== Template ID ==&lt;br /&gt;
Guard uses a template ID for choosing the templates to use.  The template ID can be chosen for a user or context using the configuration cascade.&lt;br /&gt;
&lt;br /&gt;
 com.openexchange.guard.templateID=x&lt;br /&gt;
&lt;br /&gt;
For any template below, a customized template can be created with the name x-templatename where x is the integer value of the template ID for the user.  For example, if you wanted a custom password template based on the template &amp;quot;passwordtempl.html&amp;quot; for a context of users, you could create a template &amp;quot;2-passwordtempl.html&amp;quot; and assign the value com.openexchange.guard.templateID=2 to the context.  Then, Guard will use any templates that start with &amp;quot;2-&amp;quot; for the context.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:'''&lt;br /&gt;
If no template ID is specified, or if a file specified by the template ID is not found, then the default template is used.  The default is the templates with no number prefix, i.e. &amp;quot;passwordtempl.html&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Templates ==&lt;br /&gt;
=== Emails ===&lt;br /&gt;
* guesttempl.html - Email template used when sending to a guest user (not an OX account)&lt;br /&gt;
* passwordtempl.html - Template used to send a new password to a guest user. As of 2.8, only used if newGuestsRequirePassword=true is configured&lt;br /&gt;
* oxpasswordtempl.html - Email template used when sending a new password to an OX user. No longer used after 2.6&lt;br /&gt;
* resettempl.html - Template used when sending a password reset&lt;br /&gt;
* guestresettempl.html - Template used when resetting guest account and password recovery is disabled&lt;br /&gt;
&lt;br /&gt;
=== Guest Reader ===&lt;br /&gt;
* reader.html - The main guest reader template.  THIS IS NOT CUSTOMIZABLE WITH TEMPLATE ID.  GLOBAL CHANGES ONLY.  We recommend not changing this file and using the header, footer, and style sheets for branding.&lt;br /&gt;
* header.html - Top header bar of the Guest reader&lt;br /&gt;
* footer.html - Footer of the Guest reader&lt;br /&gt;
* style.css - Style sheet for the Guest reader&lt;br /&gt;
&lt;br /&gt;
== Email Template GetText ==&lt;br /&gt;
In the HTML templates, wording is surrounded by a call to gettext, which will get the translation for the user.  It is used in a HTML call &amp;lt;$gettext(&amp;quot;text here&amp;quot;)&amp;gt;&lt;br /&gt;
Example: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;$gettext(&amp;quot;You have received this email because $from has sent you a secure email message with OX Guard. You will receive a link to the secure message in a separate email.&amp;quot;)&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
Some email templates have space for variables depending on their function.  The variable name will begin with $ such as the above example $from.&lt;br /&gt;
&lt;br /&gt;
== Guest Reader Translations ==&lt;br /&gt;
The Guest reader webpage uses i18next for translations.  If changing the header and footer such that you need translation, use a call such as &lt;br /&gt;
&lt;br /&gt;
 &amp;amp;lt;h2 data-i18n=&amp;quot;PIN Required:&amp;quot;&amp;gt;PIN Required:&amp;lt;/h2&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;data-i18n&amp;quot; property results in the inner HTML wording being replaced with the translation (if available for the specified language)&lt;br /&gt;
&lt;br /&gt;
=====Guest Translations as of Version 2.4.2-rev8=====&lt;br /&gt;
Custom Guest reader translations can be managed by creating a file custom-Lang.json located in the /var/www/html/reader/l10n (on Debian 8)&lt;br /&gt;
This custom file should contain only the translations you want to replace in the default translation-Lang.json files.&lt;br /&gt;
&lt;br /&gt;
For example, if you wanted to change the French translation of&lt;br /&gt;
&amp;quot;Welcome&amp;quot; from &amp;quot;Bienvenue&amp;quot; to &amp;quot;Bonjour&amp;quot;, you would create a file custom-FR_fr.json with the contents&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
     &amp;quot;Welcome&amp;quot; : &amp;quot;Bonjour&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reader will load the file translations-FR_fr.json first, then it will load custom and overwrite any values found.&lt;br /&gt;
&lt;br /&gt;
= Guard Product Name Customization (2.4 or 2.2.1-8+) =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Guard product name can be configured by general setting for smaller deployments, by configuration cascade, or by URL&lt;br /&gt;
&lt;br /&gt;
== Product name by configuration ==&lt;br /&gt;
&lt;br /&gt;
The configuration&lt;br /&gt;
 com.openexchange.guard.productName&lt;br /&gt;
can be defined in the guard-core.properties (2.4) or in the guard.properties file (2.2.1-8).  This product name will be passed to the UI.&lt;br /&gt;
&lt;br /&gt;
This value can also be configured at the configuration cascade level&lt;br /&gt;
&lt;br /&gt;
== Product name by URL ==&lt;br /&gt;
&lt;br /&gt;
By editing the file yml located in /opt/open-xchange/etc/as-config.yml the property&lt;br /&gt;
 guard.productName&lt;br /&gt;
can be defined based on the browser URL/IP used to address the OX backend.  This product name will the be passed to the UI to be displayed by the user.&lt;/div&gt;</summary>
		<author><name>Choeger</name></author>
	</entry>
</feed>