summaryrefslogtreecommitdiff
path: root/Architecture_and_Design
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-02-21 09:59:54 (GMT)
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2012-02-21 09:59:54 (GMT)
commitde2a5b783fb28c7ef3dee8c6fb74e13c652284cd (patch)
tree11727c86654c798ab640330173fffa8d60999141 /Architecture_and_Design
parent2bb150e84deb95bbe669fa031315b6060e8b63bd (diff)
downloadkolab-docs-de2a5b783fb28c7ef3dee8c6fb74e13c652284cd.tar.gz
Updates to the architecture and design document
Diffstat (limited to 'Architecture_and_Design')
-rw-r--r--Architecture_and_Design/en-US/Administration_Panel.xml1526
-rw-r--r--Architecture_and_Design/en-US/Authentication_amp_Authorization.xml47
-rw-r--r--Architecture_and_Design/en-US/Configuration_Management.xml384
-rw-r--r--Architecture_and_Design/en-US/Kolab_Server_Overview.xml3
4 files changed, 1960 insertions, 0 deletions
diff --git a/Architecture_and_Design/en-US/Administration_Panel.xml b/Architecture_and_Design/en-US/Administration_Panel.xml
index 8570ae1..8791392 100644
--- a/Architecture_and_Design/en-US/Administration_Panel.xml
+++ b/Architecture_and_Design/en-US/Administration_Panel.xml
@@ -123,6 +123,1532 @@
</section>
+ <section id="sect-Architecture_and_Design-Administration_Panel-Web_Administration_Panel_API">
+ <title>Web Administration Panel API</title>
+ <!-- <para>
+
+<programlisting language="Python">
+<xi:include href="http://git.kolab.org/pykolab/plain/kolabd.py" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude" />
+</programlisting>
+ </para> --> <para>
+ The web administration panel comes with an API in order to allow different, third-party interfaces, as well as the Kolab tool-chain to Kolab Groupware, to execute tasks of an administrative nature. The API uses JSON to exchange information with the API client.
+ </para>
+ <para>
+ The calls to the Web API are made to a service handler, for its methods handle the request. A call therefore looks like <emphasis>&lt;service&gt;.&lt;method&gt;</emphasis>, which is a location beneath the base URL for the API.
+ </para>
+ <para>
+ Suppose <ulink url="https://kolab-admin.example.org/api/" /> is the API base URL, then a call to service method <literal>system.authenticate</literal> would be a POST HTTP/1.1 request to <ulink url="https://kolab-admin.example.org/api/system.authenticate" />.
+ </para>
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-HTTP_Method_Convention">
+ <title>HTTP Method Convention</title>
+ <para>
+ Two HTTP methods are used: GET and POST. The GET method is generally(!) used for read-only operations, whereas the POST method is used for write operations.
+ </para>
+ <para>
+ For GET requests, the parameters (the payload) are appended to the URI requested, <ulink url="https://kolab-admin.example.org/api/domain.info?domain=example.org" />.
+ </para>
+ <note>
+ <para>
+ This restricts GET requests to specifying key-value pairs of payload information only, even though a GET parameter key can be specified more then one, creating a list of values.
+ </para>
+
+ </note>
+ <para>
+ Some read-only operations, such as <literal>user.find_by_attributes</literal> require the request to pass along multiple attributes with, potentially, multiple search parameters. These types read-only requests are the exception to the rule of using GET for read-only requests, and use POST instead.
+ </para>
+ <para>
+ For POST requests, the payload is a JSON-encoded dictionary (array) of parameter keys and values. Only strings are allowed as keys. Values for the payload may contain lists, strings, dictionaries (arrays), integers, floats, etc.
+ </para>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-Service_and_Method_Naming_Convention">
+ <title>Service and Method Naming Convention</title>
+ <para>
+ In another rule-of-thumb we outline the naming convention for services and methods.
+ </para>
+ <para>
+ Service names consist of an object name either in singular or plural form. The singular form depicts actions are placed against a single instance of an object, such as <literal>object.add</literal>, whereas the plural form depicts actions are placed against multiple instances of an object, such as <literal>objects.list</literal> or <literal>objects.search</literal>.
+ </para>
+ <para>
+ Method names often imply an action is placed against one or more objects in one request. Certain actions may be confusing though. For these we have the following rules;
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-Service_and_Method_Naming_Convention-Finding_an_object">
+ <title>Finding an object</title>
+ <para>
+ The method <literal>find</literal> is always executed against the service with the singular form of the object name. The target of calling a <literal>find</literal> method is to obtain exactly one instance of an object. The method should fail if the result set contains any number of objects not one.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-Service_and_Method_Naming_Convention-Searching_for_objects">
+ <title>Searching for objects</title>
+ <para>
+ The method <literal>search</literal> is always executed against the service with the plural form of the object name. The target of calling a <literal>search</literal> method is to obtain all matches, if any. The method should return any result set containing zero or more results.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-Standard_Response_Layout">
+ <title>Standard Response Layout</title>
+ <para>
+ The standard response layout offers a location for the request status, an error code and the corresponding message, or a result.
+ </para>
+ <para>
+ The status is the first item in the JSON dictionary. It has two possible values: <literal>OK</literal> or <literal>ERROR</literal>. Depending on the status of the request, the rest of the JSON output contains a result (OK) or the error details (ERROR).
+ </para>
+ <para>
+ A successful request looks like:
+ </para>
+ <para>
+
+<screen language="Python">{
+ "status":"OK",
+ "result": (...)
+}</screen>
+
+ </para>
+ <para>
+ A failed result however looks like:
+ </para>
+ <para>
+
+<screen language="Python">{
+ "status":"ERROR",
+ "code":&lt;integer&gt;,
+ "reason":"&lt;string&gt;"
+}</screen>
+
+ </para>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-The_domain_Service">
+ <title>The <literal>domain</literal> Service</title>
+ <para>
+ The <literal>domain</literal> service makes available actions against a single domain entity, for example 'add' or 'delete'. For actions against multiple domain entities, such as 'list' and 'search', see <xref linkend="sect-Architecture_and_Design-Web_Administration_Panel_API-The_domains_Service" />.
+ </para>
+ <section id="sect-Architecture_and_Design-The_domain_Service-domain.add_Method">
+ <title><literal>domain.add</literal> Method</title>
+ <para>
+ Depending on the technology used, quite the variety of things may need to happen when adding a domain to a Kolab Groupware deployment.
+ </para>
+ <formalpara id="form-Architecture_and_Design-domain.add_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ The following parameters MUST be specified with the <literal>domain.add</literal> API call:
+ </para>
+
+ </formalpara>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-domain.add_Method-domain">
+ <title><literal>domain</literal></title>
+ <para>
+ The domain name space to be added.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <!--
+ <para>
+ The following parameters MAY be specified alongside the required parameters:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-domain.add_Method-owner">
+ <title><literal>owner</literal></title>
+ <para>
+ If specified, MUST refer to an existing domain name space.
+ </para>
+
+ </formalpara>
+ <remark> We need to verify owner is a valid attribute to an associated domain, and/or find a different mechanism for delegation between ISP, any level of resellers, and customers. Note that perhaps also the level of delegation can be tricky (@hotmail.com hosted style) </remark>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ --> <formalpara id="form-Architecture_and_Design-domain.add_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.add_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ <example id="exam-Architecture_and_Design-Example_Client_Implementation-Example_domain.add_API_call_in_Python">
+ <title>Example <literal>domain.add</literal> API call in Python</title>
+ <para>
+ The following is an example of a call to API service method <literal>domain.add</literal>:
+ </para>
+ <para>
+
+<programlisting language="Python">import json
+import httplib
+import sys
+
+from pykolab import utils
+
+API_HOSTNAME = "kolab-admin.example.org"
+API_PORT = "443"
+API_SCHEME = "https"
+API_BASE = "/api"
+
+username = utils.ask_question("Login")
+password = utils.ask_question("Password", password=True)
+
+params = json.dumps({
+ 'username': username,
+ 'password': password
+ })
+
+if API_SCHEME == "http":
+ conn = httplib.HTTPConnection(API_HOSTNAME, API_PORT)
+elif API_SCHEME == "https":
+ conn = httplib.HTTPSConnection(API_HOSTNAME, API_PORT)
+
+conn.connect()
+conn.request('POST', "%s/system.authenticate" %(API_BASE), params)
+try:
+ response_data = json.loads(conn.getresponse().read())
+except ValueError, e:
+ print e
+ sys.exit(1)
+
+# Check status here, using response_data['status']
+
+if response_data.has_key('session_token'):
+ session_id = response_data['session_token']
+
+headers = { 'X-Session-Token': session_id }
+
+params = json.dumps({
+ 'domain': utils.ask_question("Domain")
+ })
+
+conn.request('POST', "%s/domain.add" %(API_BASE), params, headers)
+try:
+ response_data = json.loads(conn.getresponse().read())
+except ValueError, e:
+ print e
+ sys.exit(1)</programlisting>
+
+ </para>
+
+ </example>
+
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.add_Method-Response">
+ <title>Response</title>
+ <para>
+
+<screen language="Python">{
+ "status":"OK"
+}</screen>
+
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.add_Method-Server_side_Implementation_Details">
+ <title>Server-side Implementation Details</title>
+ <para>
+ On the server-side, when a domain is added, an entry is added to the default authentication and authorization database, as configured through the setting <literal>auth_mechanism</literal> in the <literal>[kolab]</literal> section of <filename>/etc/kolab/kolab.conf</filename>.
+ </para>
+
+ </formalpara>
+ <para>
+ The authentication database technology referred to itself has the necessary settings to determine how a new domain can be added. The related settings for LDAP are <literal>domain_base_dn</literal>, <literal>domain_scope</literal>, <literal>domain_filter</literal>, <literal>domain_name_attribute</literal> (also used for the RDN).
+ </para>
+ <para>
+ After checking the domain does not already exist (using administrative credentials), the domain is added using the credentials for the logged in user. This is an access control verification step only; the logged in user must have 'add' rights on the domain base distinguished name.
+ </para>
+ <para>
+ Additional steps when adding a (primary) domain name space is to create the databases and populate the root dn. Below is a snippet of script doing just that for <literal>example.org</literal> against a 389 Directory Server.
+ </para>
+
+<programlisting language="Bash">#!/bin/bash
+
+if [ $# -ne 1 ]; then
+ read -p "Domain: " domain
+else
+ domain=$1
+fi
+
+domain_db=$(echo ${domain} | sed -e 's/\./_/g')
+domain_dn=$(echo ${domain} | sed -e 's/\./,dc=/g')
+domain_dn="dc=${domain_dn}"
+
+. ./zzz-settings.sh
+
+(
+ echo "dn: associateddomain=${domain},cn=kolab,cn=config"
+ echo "associateddomain: ${domain}"
+ echo "objectClass: top"
+ echo "objectClass: inetdomain"
+ echo "objectClass: domainrelatedobject"
+ echo "objectClass: organization"
+ echo "o: ${domain}"
+ echo ""
+ echo "dn: cn=${domain_db},cn=ldbm database,cn=plugins,cn=config"
+ echo "objectClass: top"
+ echo "objectClass: extensibleObject"
+ echo "objectClass: nsBackendInstance"
+ echo "cn: ${domain_db}"
+ echo "nsslapd-suffix: ${domain_dn}"
+ echo "nsslapd-cachesize: -1"
+ echo "nsslapd-cachememsize: 10485760"
+ echo "nsslapd-readonly: off"
+ echo "nsslapd-require-index: off"
+ echo "nsslapd-directory: /var/lib/dirsrv/slapd-${instance}/db/${domain_db}"
+ echo "nsslapd-dncachememsize: 10485760"
+ echo ""
+ echo "dn: cn=$(echo ${domain_dn} | sed -e 's/,/\\2C/g' -e 's/=/\\3D/g'),cn=mapping tree,cn=config"
+ echo "objectClass: top"
+ echo "objectClass: extensibleObject"
+ echo "objectClass: nsMappingTree"
+ echo "nsslapd-state: backend"
+ echo "cn: ${domain_dn}"
+ echo "nsslapd-backend: ${domain_db}"
+ echo ""
+ echo "dn: ${domain_dn}"
+ echo "dc: $(echo ${domain} | cut -d'.' -f 1)"
+ echo "objectClass: top"
+ echo "objectClass: domain"
+ echo "aci: (targetattr=\"carLicense || description || displayName || facsimileTelephoneNumber || homePhone || homePostalAddress || initials || jpegPhoto || labeledURI || mail || mobile || pager || photo || postOfficeBox || postalAddress || postalCode || preferredDeliveryMethod || preferredLanguage || registeredAddress || roomNumber || secretary || seeAlso || st || street || telephoneNumber || telexNumber || title || userCertificate || userPassword || userSMIMECertificate || x500UniqueIdentifier\")(version 3.0; acl \"Enable self write for common attributes\"; allow (write) userdn=\"ldap:///self\";)"
+ echo "aci: (targetattr =\"*\")(version 3.0;acl \"Directory Administrators Group\";allow (all) (groupdn=\"ldap:///cn=Directory Administrators,${domain_dn}\");)"
+ echo "aci: (targetattr=\"*\")(version 3.0; acl \"Configuration Administrators Group\"; allow (all) groupdn=\"ldap:///cn=Configuration Administrators,ou=Groups,ou=TopologyManagement,o=NetscapeRoot\";)"
+ echo "aci: (targetattr=\"*\")(version 3.0; acl \"Configuration Administrator\"; allow (all) userdn=\"ldap:///uid=admin,ou=Administrators,ou=TopologyManagement,o=NetscapeRoot\";)"
+ echo "aci: (targetattr = \"*\")(version 3.0; acl \"SIE Group\"; allow (all) groupdn = \"ldap:///cn=slapd-ldap01,cn=389 Directory Server,cn=Server Group,cn=hosted04.klab.cc,ou=klab.cc,o=NetscapeRoot\";)"
+ echo ""
+ echo "dn: cn=Directory Administrators,${domain_dn}"
+ echo "objectClass: top"
+ echo "objectClass: groupofuniquenames"
+ echo "cn: Directory Administrators"
+ echo "uniqueMember: cn=Directory Manager"
+ echo ""
+
+ echo "dn: ou=Groups,${domain_dn}"
+ echo "objectClass: top"
+ echo "objectClass: organizationalunit"
+ echo "ou: Groups"
+ echo ""
+
+ echo "dn: ou=People,${domain_dn}"
+ echo "objectClass: top"
+ echo "objectClass: organizationalunit"
+ echo "ou: People"
+ echo ""
+
+ echo "dn: ou=Special Users,${domain_dn}"
+ echo "objectClass: top"
+ echo "objectClass: organizationalUnit"
+ echo "ou: Special Users"
+ echo "description: Special Administrative Accounts"
+ echo ""
+
+ echo "dn: uid=kolab-service,ou=Special Users,${domain_dn}"
+ echo "uid: kolab-service"
+ echo "givenName: Kolab"
+ echo "objectClass: top"
+ echo "objectClass: person"
+ echo "objectClass: inetOrgPerson"
+ echo "objectClass: organizationalPerson"
+ echo "sn: Service Account"
+ echo "cn: Kolab Service Account"
+ echo "userPassword: ${kolab_service_pass}"
+ echo ""
+
+ echo "dn: uid=cyrus-murder,ou=Special Users,${domain_dn}"
+ echo "uid: cyrus-murder"
+ echo "givenName: Cyrus"
+ echo "objectClass: top"
+ echo "objectClass: person"
+ echo "objectClass: inetOrgPerson"
+ echo "objectClass: organizationalPerson"
+ echo "sn: Murder"
+ echo "cn: Cyrus Murder"
+ echo "userPassword: ${cyrus_murder_pass}"
+ echo ""
+
+ echo "dn: uid=cyrus-admin,ou=Special Users,${domain_dn}"
+ echo "uid: cyrus-admin"
+ echo "givenName: Cyrus"
+ echo "objectClass: top"
+ echo "objectClass: person"
+ echo "objectClass: inetOrgPerson"
+ echo "objectClass: organizationalPerson"
+ echo "sn: Administrator"
+ echo "cn: Cyrus Administrator"
+ echo "userPassword: ${cyrus_admin_pass}"
+ echo ""
+
+) | ldapadd -x -h ${ldap_server} -D "cn=Directory Manager" -w "${dirmgr_pass_plain}" -c</programlisting>
+ <section id="sect-Architecture_and_Design-domain.add_Method-TODO">
+ <title>TODO</title>
+ <para>
+ The following is a list of things that still need to be designed and/or implemented.
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Adding an alias for a domain name space, such that "company.nl" can be specified as an alias domain name space for "company.com".
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Designating an "owner" of a domain name space, possibly through nesting (LDAP) or assigning a owner_id (SQL).
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Determining access to a domain name space for any particular set of credentials.
+ </para>
+ <para>
+ It seems, for LDAP, the server-side getEffectiveRights control is not supported. An alternative may be to probe the root dn for the domain name space using the current session bind credentials, but this may not scale. Exceptions to the probing would need to be established to make sure the known DNs are not subjected to the extensive operation(s) (such as <emphasis>cn=Directory Manager</emphasis>).
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Once a domain is added, we have to implement access control on top of it.
+ </para>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_domain_Service-domain.delete_Method">
+ <title><literal>domain.delete</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-domain.delete_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.delete_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.delete_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.delete_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_domain_Service-domain.edit_Method">
+ <title><literal>domain.edit</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-domain.edit_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.edit_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.edit_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domain.edit_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-The_domains_Service">
+ <title>The <literal>domains</literal> Service</title>
+ <section id="sect-Architecture_and_Design-The_domains_Service-domains.list_Method">
+ <title><literal>domains.list</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-domains.list_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domains.list_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domains.list_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-domains.list_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-The_group_Service">
+ <title>The <literal>group</literal> Service</title>
+ <section id="sect-Architecture_and_Design-The_group_Service-group.info_Method">
+ <title><literal>group.info</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-group.info_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ The following parameters are required:
+ </para>
+
+ </formalpara>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-group.info_Method-group">
+ <title><literal>group</literal></title>
+ <para>
+ The group to return information for.
+ </para>
+
+ </formalpara>
+ <remark> Currently, we only allow the group to be searched by the email address associated with the group. </remark>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <formalpara id="form-Architecture_and_Design-group.info_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-group.info_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-group.info_Method-Response">
+ <title>Response</title>
+ <para>
+
+<screen language="Python">{
+ "status":"OK",
+ "result": [
+ "uid=vanmeeuwen,ou=People,dc=klab,dc=cc",
+ "uid=greve,ou=People,dc=klab,dc=cc",
+ "uid=adams,ou=People,dc=klab,dc=cc",
+ "uid=wickert,ou=People,dc=klab,dc=cc",
+ "uid=machniak,ou=People,dc=klab,dc=cc",
+ "uid=bruederli,ou=People,dc=klab,dc=cc",
+ "uid=mollekopf,ou=People,dc=klab,dc=cc",
+ "uid=beecher,ou=People,dc=klab,dc=cc",
+ "uid=ayres,ou=People,dc=klab,dc=cc",
+ (...snip...)
+ ]
+}</screen>
+
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_group_Service-group.members_list_Method">
+ <title><literal>group.members_list</literal> Method</title>
+ <para>
+ The <literal>group.members_list</literal> service method lists the members of a group.
+ </para>
+ <formalpara id="form-Architecture_and_Design-group.members_list_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ The following parameters are required:
+ </para>
+
+ </formalpara>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-group.members_list_Method-group">
+ <title><literal>group</literal></title>
+ <para>
+ The group to list the members for.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <formalpara id="form-Architecture_and_Design-group.members_list_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-group.members_list_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-group.members_list_Method-Response">
+ <title>Response</title>
+ <para>
+
+<screen language="Python">{
+ "status":"OK",
+ "result": [
+ "uid=vanmeeuwen,ou=People,dc=klab,dc=cc",
+ "uid=greve,ou=People,dc=klab,dc=cc",
+ "uid=adams,ou=People,dc=klab,dc=cc",
+ "uid=wickert,ou=People,dc=klab,dc=cc",
+ "uid=machniak,ou=People,dc=klab,dc=cc",
+ "uid=bruederli,ou=People,dc=klab,dc=cc",
+ "uid=mollekopf,ou=People,dc=klab,dc=cc",
+ "uid=beecher,ou=People,dc=klab,dc=cc",
+ "uid=ayres,ou=People,dc=klab,dc=cc",
+ (...snip...)
+ ]
+}</screen>
+
+ </para>
+
+ </formalpara>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-The_system_Service">
+ <title>The <literal>system</literal> Service</title>
+ <section id="sect-Architecture_and_Design-The_system_Service-system.authenticate_Method">
+ <title><literal>system.authenticate</literal> Method</title>
+ <para>
+ Successful authentication is a prerequisite in order to be able to execute any other action against the system. Upon success, the <literal>system.authenticate</literal> API call returns a session token that MUST be supplied with all subsequent requests for the session, through the HTTP header <literal>X-Session-Token</literal>.
+ </para>
+ <formalpara id="form-Architecture_and_Design-system.authenticate_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ The following parameters MUST be supplied with a call to <literal>system.authenticate</literal>:
+ </para>
+
+ </formalpara>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-system.authenticate_Method-username">
+ <title><literal>username</literal></title>
+ <para>
+ The username.
+ </para>
+
+ </formalpara>
+ <note>
+ <para>
+ Currently, only the 'entryDN' and 'mail' attribute values are allowed as the username for an authentication request.
+ </para>
+
+ </note>
+ <para>
+ See also: <xref linkend="sect-Architecture_and_Design-Authentication_amp_Authorization-The_User_Supplied_Login" />
+ </para>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-system.authenticate_Method-password">
+ <title><literal>password</literal></title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <para>
+ The following parameters MAY be supplied with a call to <literal>system.authenticate</literal>:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-system.authenticate_Method-domain">
+ <title><literal>domain</literal></title>
+ <para>
+ With supplying the <literal>domain</literal> parameter in an authentication request,
+ </para>
+
+ </formalpara>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <formalpara id="form-Architecture_and_Design-system.authenticate_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.authenticate_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ <example id="exam-Architecture_and_Design-Example_Client_Implementation-Example_system.authenticate_API_call_in_Python">
+ <title>Example <literal>system.authenticate</literal> API call in Python</title>
+ <para>
+ The following is an example of authentication against the API in Python:
+ </para>
+ <para>
+
+<programlisting language="Python">import json
+import httplib
+import sys
+
+from pykolab import utils
+
+API_HOSTNAME = "kolab-admin.example.org"
+API_PORT = "443"
+API_SCHEME = "https"
+API_BASE = "/api"
+
+username = utils.ask_question("Login")
+password = utils.ask_question("Password", password=True)
+
+params = json.dumps({
+ 'username': username,
+ 'password': password
+ })
+
+if API_SCHEME == "http":
+ conn = httplib.HTTPConnection(API_HOSTNAME, API_PORT)
+elif API_SCHEME == "https":
+ conn = httplib.HTTPSConnection(API_HOSTNAME, API_PORT)
+
+conn.connect()
+conn.request('POST', "%s/system.authenticate" %(API_BASE), params)
+try:
+ response_data = json.loads(conn.getresponse().read())
+except ValueError, e:
+ print e
+ sys.exit(1)
+
+# Check status here, using response_data['status']
+
+if response_data.has_key('result'):
+ if response_data['result'].has_key('session_token'):
+ session_id = response_data['result']['session_token']</programlisting>
+
+ </para>
+
+ </example>
+
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.authenticate_Method-Response">
+ <title>Response</title>
+ <para>
+ The following is a response to a successful authentication request (with inserted line-breaks for readability):
+ </para>
+
+ </formalpara>
+ <para>
+
+<screen language="Python">{
+ "status":"OK",
+ "result": {
+ "user":"cn=Directory Manager",
+ "domain":"klab.cc",
+ "session_token":"ndgu4ennb6t51i4b0dvkulhvk6"
+ }
+}</screen>
+
+ </para>
+ <para>
+ The following is a reponse to an unsuccessful call to <literal>system.authenticate</literal> (with inserted line-breaks for readability):
+ </para>
+ <para>
+
+<screen language="Python">{
+ "status":"ERROR",
+ "code":500,
+ "reason":"Internal error"
+}</screen>
+
+ </para>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_system_Service-system.capabilities_Method">
+ <title><literal>system.capabilities</literal> Method</title>
+ <para>
+ For all service handlers registered, a method <literal>capabilities</literal> can be executed listing the methods available and access to them. The <literal>system.capabilities</literal> API call lists all of the registered service handlers' methods and access.
+ </para>
+ <formalpara id="form-Architecture_and_Design-system.capabilities_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.capabilities_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.capabilities_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.capabilities_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_system_Service-system.quit_Method">
+ <title><literal>system.quit</literal> Method</title>
+ <para>
+ The quit method ends the session.
+ </para>
+ <formalpara id="form-Architecture_and_Design-system.quit_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.quit_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ GET, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.quit_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.quit_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_system_Service-system.select_domain_Method">
+ <title><literal>system.select_domain</literal> Method</title>
+ <para>
+ Select the domain supplied as the current working domain. By default, users are logged in and have access to what they are authorized for in their own domain name space only. Certain users, such as <emphasis>cn=Directory Manager</emphasis>, have access to all domains. This API call allows such users to select the domain name space they are currently working on.
+ </para>
+ <formalpara id="form-Architecture_and_Design-system.select_domain_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params: domain name
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.select_domain_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.select_domain_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.select_domain_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-system.select_domain_Method-Server_side_Implementation_Details">
+ <title>Server-side Implementation Details</title>
+ <para>
+ On the server-side, when <literal>system.select_domain</literal> is called successfully, the selected domain is stored in <code>$_SESSION['user']-&gt;current_domain</code>. This is a private property, however, and the rest of the code is to use the public function <code>$_SESSION['user']-&gt;get_domain()</code>:
+ </para>
+
+ </formalpara>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-The_user_Service">
+ <title>The <literal>user</literal> Service</title>
+ <para>
+ The <literal>user</literal> service ...
+ </para>
+ <section id="sect-Architecture_and_Design-The_user_Service-user.add_Method">
+ <title><literal>user.add</literal> Method</title>
+ <formalpara id="form-Architecture_and_Design-user.add_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params: user_type_id (obtain from <literal>user_types.list</literal>)
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.add_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.add_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.add_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_Service-user.delete_Method">
+ <title><literal>user.delete</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user.delete_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.delete_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.delete_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.delete_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_Service-user.disable_Method">
+ <title><literal>user.disable</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user.disable_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.disable_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.disable_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.disable_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_Service-user.edit_Method">
+ <title><literal>user.edit</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user.edit_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.edit_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.edit_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.edit_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_Service-user.enable_Method">
+ <title><literal>user.enable</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user.enable_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.enable_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.enable_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.enable_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_Service-user.info_Method">
+ <title><literal>user.info</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user.info_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ The following parameter(s) MUST be supplied with a call to <literal>user.info</literal>:
+ </para>
+
+ </formalpara>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-user.info_Method-user">
+ <title><literal>user</literal></title>
+ <para>
+ A string allowing the user the information needs to be obtained for to be uniquely identified.
+ </para>
+
+ </formalpara>
+ <note>
+ <para>
+ Currently, only the 'entryDN' and 'mail' attribute values are allowed as the username for an authentication request.
+ </para>
+
+ </note>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <formalpara id="form-Architecture_and_Design-user.info_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ GET, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.info_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.info_Method-Response">
+ <title>Response</title>
+ <para>
+ The response to a <literal>user.info</literal> API call contains all information to a particular entry in the authentication and authorization database technology, that can be obtained using the bind credentials for the session user.
+ </para>
+
+ </formalpara>
+ <para>
+ The output is normalized for abstraction, and looks as follows, with added line-breaks for clarity:
+ </para>
+ <para>
+
+<screen language="Python">{
+ u'status': 'OK',
+ u'uid=vanmeeuwen,ou=People,dc=klab,dc=cc': {
+ u'mailalternateaddress': [
+ u'vanmeeuwen@klab.cc',
+ u'j.vanmeeuwen@klab.cc'
+ ],
+ u'displayname': u'van Meeuwen, Jeroen',
+ u'uid': u'vanmeeuwen',
+ u'mailhost': u'imap.klab.cc',
+ u'objectclass': [
+ u'top',
+ u'person',
+ u'inetOrgPerson',
+ u'organizationalPerson',
+ u'mailrecipient',
+ u'kolabInetOrgPerson',
+ u'posixAccount'
+ ],
+ u'loginshell': u'/bin/bash',
+ u'userpassword': u'{SSHA}yGEm7rdOSrTDCd/h4F5q1fx5GTvSynHU',
+ u'uidnumber': u'500',
+ u'modifiersname': u'cn=directory manager',
+ u'modifytimestamp': u'20111206153131Z',
+ u'preferredlanguage': u'en_US',
+ u'gidnumber': u'500',
+ u'createtimestamp': u'20111119171559Z',
+ u'sn': u'van Meeuwen',
+ u'homedirectory': u'/home/vanmeeuwen',
+ u'mail': u'jeroen.vanmeeuwen@klab.cc',
+ u'givenname': u'Jeroen',
+ u'creatorsname': u'cn=directory manager',
+ u'cn': u'Jeroen van Meeuwen'
+ }
+}</screen>
+
+ </para>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_Service-user.search_Method">
+ <title><literal>user.search</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user.search_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.search_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ GET, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.search_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user.search_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-The_user_types_Service">
+ <title>The <literal>user_types</literal> Service</title>
+ <para>
+ The <literal>user_types</literal> service ...
+ </para>
+ <section id="sect-Architecture_and_Design-The_user_types_Service-user_types.add_Method">
+ <title><literal>user_types.add</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user_types.add_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.add_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.add_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.add_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_types_Service-user_types.delete_Method">
+ <title><literal>user_types.delete</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user_types.delete_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.delete_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.delete_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.delete_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_types_Service-user_types.edit_Method">
+ <title><literal>user_types.edit</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user_types.edit_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.edit_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.edit_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.edit_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_user_types_Service-user_types.list_Method">
+ <title><literal>user_types.list</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-user_types.list_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.list_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.list_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-user_types.list_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Web_Administration_Panel_API-The_users_Service">
+ <title>The <literal>users</literal> Service</title>
+ <para>
+ The <literal>users</literal> service ...
+ </para>
+ <section id="sect-Architecture_and_Design-The_users_Service-users.list_Method">
+ <title><literal>users.list</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-users.list_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-users.list_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-users.list_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-users.list_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-The_users_Service-users.search_Method">
+ <title><literal>users.search</literal> Method</title>
+ <para>
+ para
+ </para>
+ <formalpara id="form-Architecture_and_Design-users.search_Method-Parameters">
+ <title>Parameters</title>
+ <para>
+ params
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-users.search_Method-HTTP_Methods">
+ <title>HTTP Method(s)</title>
+ <para>
+ POST, with an <literal>X-Session-Token</literal> HTTP/1.1 header.
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-users.search_Method-Example_Client_Implementation">
+ <title>Example Client Implementation</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+ <formalpara id="form-Architecture_and_Design-users.search_Method-Response">
+ <title>Response</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </section>
+
+
+ </section>
+
+
+ </section>
+
</chapter>
diff --git a/Architecture_and_Design/en-US/Authentication_amp_Authorization.xml b/Architecture_and_Design/en-US/Authentication_amp_Authorization.xml
index aab178b..61e1200 100644
--- a/Architecture_and_Design/en-US/Authentication_amp_Authorization.xml
+++ b/Architecture_and_Design/en-US/Authentication_amp_Authorization.xml
@@ -8,6 +8,53 @@
<para>
TODO
</para>
+ <section id="sect-Architecture_and_Design-Authentication_amp_Authorization-The_User_Supplied_Login">
+ <title>The User Supplied Login</title>
+ <para>
+ The login username can take one of many forms:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-The_User_Supplied_Login-userrealm">
+ <title>user@realm</title>
+ <para>
+ map the realm
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-The_User_Supplied_Login-userdomain.tld">
+ <title>user@domain.tld</title>
+ <para>
+ Note that domain.tld is actually a realm in the context of authn. and authz.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-The_User_Supplied_Login-user">
+ <title>user</title>
+ <para>
+ primary_domain, default realm, or something derived from other metadata (such as reverse lookup on connection IP address if available)
+ </para>
+
+ </formalpara>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+ <para>
+ It is not uncommon to allow a user to login with either of a uid, mail or alias, each either qualified or unqualified (i.e. uid@domain.tld while 'uid' attribute value may only be 'uid').
+ </para>
+
+ </section>
+
<section id="sect-Architecture_and_Design-Authentication_amp_Authorization-LDAP">
<title>LDAP</title>
<para>
diff --git a/Architecture_and_Design/en-US/Configuration_Management.xml b/Architecture_and_Design/en-US/Configuration_Management.xml
index 4ad714c..672afff 100644
--- a/Architecture_and_Design/en-US/Configuration_Management.xml
+++ b/Architecture_and_Design/en-US/Configuration_Management.xml
@@ -32,5 +32,389 @@
</itemizedlist>
</para>
+ <section id="sect-Architecture_and_Design-Configuration_Management-Kolab_Configuration_File">
+ <title>Kolab Configuration File</title>
+ <para>
+ The Kolab configuration file is <filename>/etc/kolab/kolab.conf</filename>.
+ </para>
+ <note>
+ <title>TODO</title>
+ <para>
+ This does not take into account using POSIX permissions for command-line users using the toolchain.
+ </para>
+
+ </note>
+ <para>
+ The format of the configuration file is the INI format, which consists of the following syntax:
+ </para>
+ <para>
+
+<screen>[section]
+; comment line
+
+key1 = value
+key2 = value
+ continued value for key2</screen>
+
+ </para>
+ <para>
+ The configuration file has a mandatory section, <literal>[kolab]</literal>, which controls much of the information to the base of the Kolab deployment.
+ </para>
+ <section id="sect-Architecture_and_Design-Kolab_Configuration_File-kolab">
+ <title>[kolab]</title>
+ <para>
+ The following is an overview of settings in the <literal>[kolab]</literal> section:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-kolab-auth_mechanism_ldap">
+ <title><literal>auth_mechanism</literal> (<emphasis>ldap</emphasis>)</title>
+ <para>
+ The authentication and authorization database technology to use for the primary domain name space in this Kolab deployment. If not set, defaults to a value of 'ldap'. Possible options include: 'ldap'.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-kolab-primary_domain_pykolab.constants.domainname">
+ <title><literal>primary_domain</literal> (<emphasis>pykolab.constants.domainname</emphasis>)</title>
+ <para>
+ The primary domain name space for this Kolab deployment. If not set, defaults to the value of the PyKolab constant <literal>domainname</literal>, which is derived from the system fully qualified domain name.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-kolab-imap_backend_cyrus_imap">
+ <title><literal>imap_backend</literal> (<emphasis>cyrus-imap</emphasis>)</title>
+ <para>
+ The IMAP backend technology used.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-kolab-default_quota_None">
+ <title><literal>default_quota</literal> (<emphasis>None</emphasis>)</title>
+ <para>
+ Default quota to apply to user mailboxes. Any integer representing a number of kilobytes will do. Defaults to 'None', which is actually to say, no default quota will be applied.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-kolab-virtual_domains_userid">
+ <title><literal>virtual_domains</literal> (<emphasis>userid</emphasis>)</title>
+ <para>
+ In which mode the IMAP 'virtual_domains' feature is enabled. Not in use yet.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Kolab_Configuration_File-ldap">
+ <title>[ldap]</title>
+ <para>
+ The primary LDAP settings are contained within this section. The following settings are available:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-ldap_uri_ldaplocalhost389">
+ <title><literal>ldap_uri</literal> (<emphasis>ldap://localhost:389</emphasis>)</title>
+ <para>
+ The URI to the LDAP server. Contains only the scheme ('ldap', 'ldaps'), the LDAP server connection address (an IP address or DNS name), and the port to use.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-base_dn_None">
+ <title><literal>base_dn</literal> (<emphasis>None</emphasis>)</title>
+ <para>
+ This setting contains the absolute top-level that Kolab is allowed to use. While most commonly the same value as the root distinguished name (root dn) for the tree, for example <emphasis>dc=example,dc=org</emphasis> this just is not always the case.
+ </para>
+
+ </formalpara>
+ <para>
+ Despite the fact that we can generate a domain-component oriented naming scheme base dn from the domain name space configured as or believed to be the primary domain, we require configuration of the overall base distinguished name (base dn) as LDAP trees may use a non-domain component oriented naming scheme, such as <emphasis>o=organization,c=nl</emphasis>, or use a different level of depth.
+ </para>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-bind_dn_None">
+ <title><literal>bind_dn</literal> (<emphasis>None</emphasis>)</title>
+ <para>
+ The distinguished name of the account to use for bind operations. This is (or should be) part of a set of bind credentials used as a last resort only.
+ </para>
+
+ </formalpara>
+ <para>
+ If you have other, more functionally specific bind credentials configured as well, set this to the bind dn which has the least privileges (i.e. an anonymous user).
+ </para>
+ <para>
+ If you have no other functionally more specific bind credentials configured, set this to the bind dn used to allow the most actions to be executed against the LDAP server, for example <emphasis>cn=Directory Manager</emphasis>.
+ </para>
+ <para>
+ See <xref linkend="sect-Architecture_and_Design-Kolab_Configuration_File-Use_of_Bind_Credentials" /> for more information on configuring functional specific bind credentials.
+ </para>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-bind_pw_None">
+ <title><literal>bind_pw</literal> (<emphasis>None</emphasis>)</title>
+ <para>
+ The password corresponding with the bind dn configured in <xref linkend="form-Architecture_and_Design-ldap-bind_dn_None" />.
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-auth_attrs_mail">
+ <title><literal>auth_attrs</literal> (<emphasis>mail</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-quota_attribute_mailquota">
+ <title><literal>quota_attribute</literal> (<emphasis>mailquota</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-mailserver_attribute_mailhost">
+ <title><literal>mailserver_attribute</literal> (<emphasis>mailhost</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-user_base_dn_base_dns">
+ <title><literal>user_base_dn</literal> (<emphasis>%(base_dn)s</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-user_filter_objectClass">
+ <title><literal>user_filter</literal> (<emphasis>(objectClass=*)</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-user_scope_sub">
+ <title><literal>user_scope</literal> (<emphasis>sub</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-kolab_user_base_dn_base_dns">
+ <title><literal>kolab_user_base_dn</literal> (<emphasis>%(base_dn)s</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-kolab_user_filter_objectClass">
+ <title><literal>kolab_user_filter</literal> (<emphasis>(objectClass=*)</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-kolab_user_scope_sub">
+ <title><literal>kolab_user_scope</literal> (<emphasis>sub</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-special_user_base_dn_base_dns">
+ <title><literal>special_user_base_dn</literal> (<emphasis>%(base_dn)s</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-special_user_filter_objectClass">
+ <title><literal>special_user_filter</literal> (<emphasis>(objectClass=*)</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-special_user_scope_sub">
+ <title><literal>special_user_scope</literal> (<emphasis>sub</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-group_base_dn_base_dns">
+ <title><literal>group_base_dn</literal> (<emphasis>%(base_dn)s</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-group_filter_objectClass">
+ <title><literal>group_filter</literal> (<emphasis>(objectClass=*)</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-group_scope_sub">
+ <title><literal>group_scope</literal> (<emphasis>sub</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-domain_base_dn_base_dns">
+ <title><literal>domain_base_dn</literal> (<emphasis>%(base_dn)s</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-domain_filter_objectClass">
+ <title><literal>domain_filter</literal> (<emphasis>(objectClass=*)</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-domain_scope_sub">
+ <title><literal>domain_scope</literal> (<emphasis>sub</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-domain_name_attribute_associateddomain">
+ <title><literal>domain_name_attribute</literal> (<emphasis>associateddomain</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+ <listitem>
+ <formalpara id="form-Architecture_and_Design-ldap-domain_rootdn_attribute_inetdomainbasedn">
+ <title><literal>domain_rootdn_attribute</literal> (<emphasis>inetdomainbasedn</emphasis>)</title>
+ <para>
+ para
+ </para>
+
+ </formalpara>
+
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Kolab_Configuration_File-A_Base_DN_for_Every_Type">
+ <title>A Base DN for Every Type</title>
+ <para>
+ The configuration can hold a base distinguished name setting for every type of account or group available in the Kolab deployment.
+ </para>
+ <para>
+ When the configuration is used, the Kolab programs attempt to get user or group type specific settings first, and fall back onto the generic setting. When, for example, the base dn for Kolab users is needed, first the setting <literal>kolab_user_base_dn</literal> is obtained from the configuration, and should it not have been configured, it will fall back to using <literal>user_base_dn</literal>. Should that setting also not be available, the program will fall back to using <literal>base_dn</literal>.
+ </para>
+ <para>
+ The configuration for a particular type of user or group primarily serves large LDAP directories.
+ </para>
+
+ </section>
+
+ <section id="sect-Architecture_and_Design-Kolab_Configuration_File-Use_of_Bind_Credentials">
+ <title>Use of Bind Credentials</title>
+ <para>
+ The configuration can hold a series of bind credentials, ...;
+ </para>
+
+ </section>
+
+
+ </section>
+
+
</chapter>
diff --git a/Architecture_and_Design/en-US/Kolab_Server_Overview.xml b/Architecture_and_Design/en-US/Kolab_Server_Overview.xml
index 74f0149..af7a726 100644
--- a/Architecture_and_Design/en-US/Kolab_Server_Overview.xml
+++ b/Architecture_and_Design/en-US/Kolab_Server_Overview.xml
@@ -183,6 +183,9 @@
There is a certain minimal amount of information that Kolab requires to be available in any authentication database, such as the credentials that need to be supplied by a client in order to verify the identity of the user. Which details of those credentials are stored in the authentication database very much depends on the authentication technology used. For a Kerberos (v5) deployment for example, the username and realm would suffice (the ticket is verified with the KDC, and no password exchange is required). For an LDAP deployment however, any unique attribute value, or part thereof, within the search scope may be used in combination with the password needed for a fast-bind operation.
</para>
<para>
+ It is worth noting that ultimately, all authentication is based on one or more shared secrets. In Kerberos, those shared secrets are called keytabs, and with LDAP, MySQL and PAM for example, this is the user's password. As all authentication is based on the principle of sharing a secret, the exchange and verification of the shared secret is crucial to the architecture of an infrastructure using any of the aforementioned authentication technologies.
+ </para>
+ <para>
Authorization for a user can be separate from the authentication. For example, user <literal>john@doe.org</literal> can be authorized as <literal>john.doe@example.org</literal>, or even <literal>max.imum@example.org</literal> if necessary. Additionally, groups of users are often used as a simple way of authorizing larger numbers of users.
</para>