Add preliminary xmlrpc server docs

This commit is contained in:
Miles Lott 2001-09-14 20:13:45 +00:00
parent e2f46ea462
commit 6fb62e52b3
10 changed files with 3536 additions and 0 deletions

View File

@ -0,0 +1,296 @@
<HTML
><HEAD
><TITLE
> Business layer requests
</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.64
"><LINK
REL="HOME"
TITLE=" phpGroupWare XML-RPC/SOAP Methodology
"
HREF="phpgw_server.html"><LINK
REL="PREVIOUS"
TITLE=" phpGroupWare XML-RPC/SOAP Methodology
"
HREF="phpgw_server.html"><LINK
REL="NEXT"
TITLE=" More to come...
"
HREF="phpgw_server-2.html"></HEAD
><BODY
CLASS="SECT1"
><DIV
CLASS="NAVHEADER"
><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>phpGroupWare XML-RPC/SOAP Methodology</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="phpgw_server.html"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="phpgw_server-2.html"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="AEN33"
>Business layer requests</A
></H1
><P
> Once a successful login return packet has been received and sessionid/kp3 have been extracted, every subsequent packet sent to the phpgroupware server must be preceded by an Authorization header. Here is a sample header:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>POST /phpgroupware/xmlrpc.php HTTP/1.0
User-Agent: PHP XMLRPC 1.0
Host: my.local.host
Authorization: Basic ZDgxNDIyZDRkYjg5NDEyNGNiMzZlMDhhZTdlYzAxZmY6NTU3YzkyYjBmNGE4ZDVlOTUzMzI2YmU2OTQyNjM3YjQ=
Content-Type: text/xml
Content-Length: 875
</PRE
></TD
></TR
></TABLE
><P
> The longish string is a base64 encoding of the $sessionid . ':' . $kp3. For now this is our only supported authentication method. Additional methods would probably also affect the methodCalls. This is certainly open to discussion. Following is a typical request for some contact data:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;?xml version="1.0"?&#62;
&#60;methodCall&#62;
&#60;methodName&#62;addressbook.boaddressbook.read_entries&#60;/methodName&#62;
&#60;params&#62;
&#60;param&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;start&#60;/name&#62;
&#60;value&#62;&#60;string&#62;1&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;limit&#60;/name&#62;
&#60;value&#62;&#60;string&#62;5&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;fields&#60;/name&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;n_given&#60;/name&#62;
&#60;value&#62;&#60;string&#62;n_given&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;n_family&#60;/name&#62;
&#60;value&#62;&#60;string&#62;n_family&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;/struct&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;query&#60;/name&#62;
&#60;value&#62;&#60;string&#62;&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;filter&#60;/name&#62;
&#60;value&#62;&#60;string&#62;&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;sort&#60;/name&#62;
&#60;value&#62;&#60;string&#62;&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;order&#60;/name&#62;
&#60;value&#62;&#60;string&#62;&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;/struct&#62;&#60;/value&#62;
&#60;/param&#62;
&#60;/params&#62;
&#60;/methodCall&#62;
</PRE
></TD
></TR
></TABLE
><P
> Successful response:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;?xml version="1.0"?&#62;
&#60;methodResponse&#62;
&#60;params&#62;
&#60;param&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;0&#60;/name&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;id&#60;/name&#62;
&#60;value&#62;&#60;string&#62;1&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;lid&#60;/name&#62;
&#60;value&#62;&#60;string&#62;&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;tid&#60;/name&#62;
&#60;value&#62;&#60;string&#62;n&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;owner&#60;/name&#62;
&#60;value&#62;&#60;string&#62;500&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;access&#60;/name&#62;
&#60;value&#62;&#60;string&#62;private&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;cat_id&#60;/name&#62;
&#60;value&#62;&#60;string&#62;1&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;n_given&#60;/name&#62;
&#60;value&#62;&#60;string&#62;Alan&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;/struct&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;1&#60;/name&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;id&#60;/name&#62;
&#60;value&#62;&#60;string&#62;2&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;lid&#60;/name&#62;
&#60;value&#62;&#60;string&#62;&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;tid&#60;/name&#62;
&#60;value&#62;&#60;string&#62;n&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;owner&#60;/name&#62;
&#60;value&#62;&#60;string&#62;500&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;access&#60;/name&#62;
&#60;value&#62;&#60;string&#62;private&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;cat_id&#60;/name&#62;
&#60;value&#62;&#60;string&#62;1&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;n_given&#60;/name&#62;
&#60;value&#62;&#60;string&#62;Andy&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;/struct&#62;&#60;/value&#62;
&#60;/member&#62;
...
</PRE
></TD
></TR
></TABLE
><P
> Unauthorized access attempt returns:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;methodResponse&#62;
&#60;params&#62;
&#60;param&#62;
&#60;value&#62;&#60;string&#62;UNAUTHORIZED&#60;/string&#62;&#60;/value&#62;
&#60;/param&#62;
&#60;/params&#62;
&#60;/methodResponse&#62;
</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="phpgw_server.html"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="phpgw_server.html"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="phpgw_server-2.html"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>phpGroupWare XML-RPC/SOAP Methodology</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>More to come...</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

View File

@ -0,0 +1,122 @@
<HTML
><HEAD
><TITLE
> More to come...
</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.64
"><LINK
REL="HOME"
TITLE=" phpGroupWare XML-RPC/SOAP Methodology
"
HREF="phpgw_server.html"><LINK
REL="PREVIOUS"
TITLE=" Business layer requests
"
HREF="phpgw_server-1.html"></HEAD
><BODY
CLASS="SECT1"
><DIV
CLASS="NAVHEADER"
><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>phpGroupWare XML-RPC/SOAP Methodology</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="phpgw_server-1.html"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
>&nbsp;</TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="AEN43"
>More to come...</A
></H1
><P
> Documenting every single call will be difficult, but should be done. In leiu of this, please see the class.bo{APPNAME}.inc.php files in each application/inc directory in the phpgroupware cvs. In this file will be a list_methods() function, which returns the information to the server about input/output structure for each call. If the file does not have this function, then it is not yet workable via this interface. As for the actual functions, they are also in this file. Generally, they will all accept associative array input and return same, but not always. This code is in flux, have fun.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="phpgw_server-1.html"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="phpgw_server.html"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>&nbsp;</TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Business layer requests</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>&nbsp;</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

Binary file not shown.

View File

@ -0,0 +1,305 @@
<HTML
><HEAD
><TITLE
> phpGroupWare XML-RPC/SOAP Methodology
</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.64
"><LINK
REL="NEXT"
TITLE=" Business layer requests
"
HREF="phpgw_server-1.html"></HEAD
><BODY
CLASS="ARTICLE"
><DIV
CLASS="ARTICLE"
><DIV
CLASS="TITLEPAGE"
><H1
CLASS="TITLE"
><A
NAME="AEN2"
>phpGroupWare XML-RPC/SOAP Methodology</A
></H1
><H3
CLASS="AUTHOR"
><A
NAME="AEN4"
></A
></H3
><HR></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="AEN8"
>System level requests</A
></H1
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN10"
>Login and authentication</A
></H2
><P
> Authentication for user logins is handled internally no differently than for the typical phpGroupWare login via web browser. Server logins, added for XML-RPC and SOAP, are only slightly different. For either protocol, user and server login and authentication and subsequent requests are handled by their respective server apps, xmlrpc.php and soap.php. A server is identified by a custom HTTP header, without which a normal user login will be undertaken.
</P
><P
> A client or server sends the appropriate XML-RPC or SOAP packet containing host, user, and password information to the phpgw server. The server then assigns a sessionid and key, which is returned to the client in the appropriate format.
</P
><P
> Our current method for authenticating requests after successful login is via the Authorization: Basic HTTP header to be sent by the client or requesting server. The format of this header is a base64 encoding of the assigned sessionid and kp3 variables, seperated by a ':'.
</P
><P
> Further security may be obtained by using SSL on the client and server. In the future, we may encrypt/descrypt the data on either end, or at least provide this as an option. The sessionid and key variables will make this possible, and relatively secure.
</P
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN16"
>system.login</A
></H3
><P
> The first request a client will make is the system.login method. Here is a sample of a server login packet in XML-RPC:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;?xml version="1.0"?&#62;
&#60;methodCall&#62;
&#60;methodName&#62;system.login&#60;/methodName&#62;
&#60;params&#62;
&#60;param&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;server_name&#60;/name&#62;
&#60;value&#62;&#60;string&#62;my.host.name&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;username&#60;/name&#62;
&#60;value&#62;&#60;string&#62;bubba&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;password&#60;/name&#62;
&#60;value&#62;&#60;string&#62;gump&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62; &#60;/struct&#62;&#60;/value&#62;
&#60;/param&#62;
&#60;/params&#62;
&#60;/methodCall&#62;
</PRE
></TD
></TR
></TABLE
><P
> And the same in SOAP:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;?xml version="1.0"?&#62;
&#60;SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:si="http://soapinterop.org/xsd"
xmlns:ns6="http://soapinterop.org" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&#62;
&#60;SOAP-ENV:Body&#62; &#60;ns6:system_login&#62;
&#60;server_name xsi:type=":string"&#62;my.host.name&#60;/server_name&#62;
&#60;username xsi:type=":string"&#62;bubba&#60;/username&#62;
&#60;password xsi:type=":string"&#62;gump&#60;/password&#62;
&#60;/ns6:system_login&#62;
&#60;/SOAP-ENV:Body&#62;
&#60;/SOAP-ENV:Envelope&#62;
</PRE
></TD
></TR
></TABLE
><P
> The same style of packet would be required for a user/client login. A successful login should yield the following reply:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;methodResponse&#62;
&#60;params&#62;
&#60;param&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;sessionid&#60;/name&#62;
&#60;value&#62;&#60;string&#62;cf5c5534307562fc57915608377db007&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;kp3&#60;/name&#62;
&#60;value&#62;&#60;string&#62;2fe54daa11c8d52116788aa3f93cb70e&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;/struct&#62;&#60;/value&#62;
&#60;/param&#62;
&#60;/params&#62;
&#60;/methodResponse&#62;
</PRE
></TD
></TR
></TABLE
><P
> And a failed login:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;methodResponse&#62;
&#60;params&#62;
&#60;param&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;GOAWAY&#60;/name&#62;
&#60;value&#62;&#60;string&#62;XOXO&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;/struct&#62;&#60;/value&#62;
&#60;/param&#62;
&#60;/params&#62;
&#60;/methodResponse&#62;
</PRE
></TD
></TR
></TABLE
><P
> eqweqw
</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="AEN27"
>system.logout</A
></H3
><P
> Logout:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;?xml version="1.0"?&#62;
&#60;methodCall&#62;
&#60;methodName&#62;system.logout&#60;/methodName&#62;
&#60;params&#62; &#60;param&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;sessionid&#60;/name&#62;
&#60;value&#62;&#60;string&#62;ea35cac53d2c12bd05caecd97304478a&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;member&#62;&#60;name&#62;kp3&#60;/name&#62;
&#60;value&#62;&#60;string&#62;4f2b256e0da4e7cbbebaac9f1fc8ca4a&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;/struct&#62;&#60;/value&#62;
&#60;/param&#62;
&#60;/params&#62;
&#60;/methodCall&#62;
</PRE
></TD
></TR
></TABLE
><P
> Logout worked:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#60;methodResponse&#62;
&#60;params&#62;
&#60;param&#62;
&#60;value&#62;&#60;struct&#62;
&#60;member&#62;&#60;name&#62;GOODBYE&#60;/name&#62;
&#60;value&#62;&#60;string&#62;XOXO&#60;/string&#62;&#60;/value&#62;
&#60;/member&#62;
&#60;/struct&#62;&#60;/value&#62;
&#60;/param&#62;
&#60;/params&#62;
&#60;/methodResponse&#62;
</PRE
></TD
></TR
></TABLE
></DIV
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="phpgw_server-1.html"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Business layer requests</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

View File

@ -0,0 +1,713 @@
#LyX 1.1 created this file. For more info see http://www.lyx.org/
\lyxformat 218
\textclass docbook
\language english
\inputencoding auto
\fontscheme default
\graphics default
\paperfontsize default
\spacing single
\papersize Default
\paperpackage a4
\use_geometry 0
\use_amsmath 0
\paperorientation portrait
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\quotes_times 2
\papercolumns 1
\papersides 1
\paperpagestyle default
\layout Title
phpGroupWare XML-RPC/SOAP Methodology
\layout Author
Miles Lott
\layout Author
milosch@phpgroupware.org
\layout Date
August 23, 2001
\layout Standard
additions made September 3, 2001.
\layout Standard
This document is very preliminary, but describes a working system.
\layout Section
System level requests
\layout Subsection
Login and authentication
\layout Standard
Authentication for user logins is handled internally no differently than
for the typical phpGroupWare login via web browser.
Server logins, added for XML-RPC and SOAP, are only slightly different.
For either protocol, user and server login and authentication and subsequent
requests are handled by their respective server apps, xmlrpc.php and soap.php.
A server is identified by a custom HTTP header, without which a normal
user login will be undertaken.
\layout Standard
A client or server sends the appropriate XML-RPC or SOAP packet containing
host, user, and password information to the phpgw server.
The server then assigns a sessionid and key, which is returned to the client
in the appropriate format.
\layout Standard
Our current method for authenticating requests after successful login is
via the Authorization: Basic HTTP header to be sent by the client or requesting
server.
The format of this header is a base64 encoding of the assigned sessionid
and kp3 variables, seperated by a ':'.
\layout Standard
Further security may be obtained by using SSL on the client and server.
In the future, we may encrypt/descrypt the data on either end, or at least
provide this as an option.
The sessionid and key variables will make this possible, and relatively
secure.
\layout Subsubsection
system.login
\layout Standard
The first request a client will make is the system.login method.
Here is a sample of a server login packet in XML-RPC:
\layout Code
<?xml version="1.0"?>
\layout Code
<methodCall>
\layout Code
<methodName>system.login</methodName>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>server_name</name>
\layout Code
<value><string>my.host.name</string></value>
\layout Code
</member>
\layout Code
<member><name>username</name>
\layout Code
<value><string>bubba</string></value>
\layout Code
</member>
\layout Code
<member><name>password</name>
\layout Code
<value><string>gump</string></value>
\layout Code
</member> </struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodCall>
\layout Standard
And the same in SOAP:
\layout Code
<?xml version="1.0"?>
\layout Code
<SOAP-ENV:Envelope
\layout Code
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.
org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:si="http://soapi
nterop.org/xsd"
\layout Code
xmlns:ns6="http://soapinterop.org" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.o
rg/soap/encoding/">
\layout Code
<SOAP-ENV:Body> <ns6:system_login>
\layout Code
<server_name xsi:type=":string">my.host.name</server_name>
\layout Code
<username xsi:type=":string">bubba</username>
\layout Code
<password xsi:type=":string">gump</password>
\layout Code
</ns6:system_login>
\layout Code
</SOAP-ENV:Body>
\layout Code
</SOAP-ENV:Envelope>
\layout Standard
The same style of packet would be required for a user/client login.
A successful login should yield the following reply:
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>sessionid</name>
\layout Code
<value><string>cf5c5534307562fc57915608377db007</string></value>
\layout Code
</member>
\layout Code
<member><name>kp3</name>
\layout Code
<value><string>2fe54daa11c8d52116788aa3f93cb70e</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodResponse>
\layout Standard
And a failed login:
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>GOAWAY</name>
\layout Code
<value><string>XOXO</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodResponse>
\layout Standard
eqweqw
\layout Subsubsection
system.logout
\layout Standard
Logout:
\layout Code
<?xml version="1.0"?>
\layout Code
<methodCall>
\layout Code
<methodName>system.logout</methodName>
\layout Code
<params> <param>
\layout Code
<value><struct>
\layout Code
<member><name>sessionid</name>
\layout Code
<value><string>ea35cac53d2c12bd05caecd97304478a</string></value>
\layout Code
</member>
\layout Code
<member><name>kp3</name>
\layout Code
<value><string>4f2b256e0da4e7cbbebaac9f1fc8ca4a</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodCall>
\layout Standard
Logout worked:
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>GOODBYE</name>
\layout Code
<value><string>XOXO</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodResponse>
\layout Section
Business layer requests
\layout Standard
Once a successful login return packet has been received and sessionid/kp3
have been extracted, every subsequent packet sent to the phpgroupware server
must be preceded by an Authorization header.
Here is a sample header:
\layout Code
POST /phpgroupware/xmlrpc.php HTTP/1.0
\layout Code
User-Agent: PHP XMLRPC 1.0
\layout Code
Host: my.local.host
\layout Code
Authorization: Basic ZDgxNDIyZDRkYjg5NDEyNGNiMzZlMDhhZTdlYzAxZmY6NTU3YzkyYjBmNGE
4ZDVlOTUzMzI2YmU2OTQyNjM3YjQ=
\layout Code
Content-Type: text/xml
\layout Code
Content-Length: 875
\layout Standard
The longish string is a base64 encoding of the $sessionid .
':' .
$kp3.
For now this is our only supported authentication method.
Additional methods would probably also affect the methodCalls.
This is certainly open to discussion.
Following is a typical request for some contact data:
\layout Code
<?xml version="1.0"?>
\layout Code
<methodCall>
\layout Code
<methodName>addressbook.boaddressbook.read_entries</methodName>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>start</name>
\layout Code
<value><string>1</string></value>
\layout Code
</member>
\layout Code
<member><name>limit</name>
\layout Code
<value><string>5</string></value>
\layout Code
</member>
\layout Code
<member><name>fields</name>
\layout Code
<value><struct>
\layout Code
<member><name>n_given</name>
\layout Code
<value><string>n_given</string></value>
\layout Code
</member>
\layout Code
<member><name>n_family</name>
\layout Code
<value><string>n_family</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</member>
\layout Code
<member><name>query</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>filter</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>sort</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>order</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodCall>
\layout Standard
Successful response:
\layout Code
<?xml version="1.0"?>
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>0</name>
\layout Code
<value><struct>
\layout Code
<member><name>id</name>
\layout Code
<value><string>1</string></value>
\layout Code
</member>
\layout Code
<member><name>lid</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>tid</name>
\layout Code
<value><string>n</string></value>
\layout Code
</member>
\layout Code
<member><name>owner</name>
\layout Code
<value><string>500</string></value>
\layout Code
</member>
\layout Code
<member><name>access</name>
\layout Code
<value><string>private</string></value>
\layout Code
</member>
\layout Code
<member><name>cat_id</name>
\layout Code
<value><string>1</string></value>
\layout Code
</member>
\layout Code
<member><name>n_given</name>
\layout Code
<value><string>Alan</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</member>
\layout Code
<member><name>1</name>
\layout Code
<value><struct>
\layout Code
<member><name>id</name>
\layout Code
<value><string>2</string></value>
\layout Code
</member>
\layout Code
<member><name>lid</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>tid</name>
\layout Code
<value><string>n</string></value>
\layout Code
</member>
\layout Code
<member><name>owner</name>
\layout Code
<value><string>500</string></value>
\layout Code
</member>
\layout Code
<member><name>access</name>
\layout Code
<value><string>private</string></value>
\layout Code
</member>
\layout Code
<member><name>cat_id</name>
\layout Code
<value><string>1</string></value>
\layout Code
</member>
\layout Code
<member><name>n_given</name>
\layout Code
<value><string>Andy</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</member>
\layout Code
...
\layout Standard
Unauthorized access attempt returns:
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><string>UNAUTHORIZED</string></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodResponse>
\layout Section
More to come...
\layout Standard
Documenting every single call will be difficult, but should be done.
In leiu of this, please see the class.bo{APPNAME}.inc.php files in each applicatio
n/inc directory in the phpgroupware cvs.
In this file will be a list_methods() function, which returns the information
to the server about input/output structure for each call.
If the file does not have this function, then it is not yet workable via
this interface.
As for the actual functions, they are also in this file.
Generally, they will all accept associative array input and return same,
but not always.
This code is in flux, have fun.
\the_end

View File

@ -0,0 +1,713 @@
#LyX 1.1 created this file. For more info see http://www.lyx.org/
\lyxformat 218
\textclass docbook
\language english
\inputencoding auto
\fontscheme default
\graphics default
\paperfontsize default
\spacing single
\papersize Default
\paperpackage a4
\use_geometry 0
\use_amsmath 0
\paperorientation portrait
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\quotes_times 2
\papercolumns 1
\papersides 1
\paperpagestyle default
\layout Title
phpGroupWare XML-RPC/SOAP Methodology
\layout Author
Miles Lott
\layout Author
milosch@phpgroupware.org
\layout Date
August 23, 2001
\layout Standard
additions made September 3, 2001.
\layout Standard
This document is very preliminary, but describes a working system.
\layout Section
System level requests
\layout Subsection
Login and authentication
\layout Standard
Authentication for user logins is handled internally no differently than
for the typical phpGroupWare login via web browser.
Server logins, added for XML-RPC and SOAP, are only slightly different.
For either protocol, user and server login and authentication and subsequent
requests are handled by their respective server apps, xmlrpc.php and soap.php.
A server is identified by a custom HTTP header, without which a normal
user login will be undertaken.
\layout Standard
A client or server sends the appropriate XML-RPC or SOAP packet containing
host, user, and password information to the phpgw server.
The server then assigns a sessionid and key, which is returned to the client
in the appropriate format.
\layout Standard
Our current method for authenticating requests after successful login is
via the Authorization: Basic HTTP header to be sent by the client or requesting
server.
The format of this header is a base64 encoding of the assigned sessionid
and kp3 variables, seperated by a ':'.
\layout Standard
Further security may be obtained by using SSL on the client and server.
In the future, we may encrypt/descrypt the data on either end, or at least
provide this as an option.
The sessionid and key variables will make this possible, and relatively
secure.
\layout Subsubsection
system.login
\layout Standard
The first request a client will make is the system.login method.
Here is a sample of a server login packet in XML-RPC:
\layout Code
<?xml version="1.0"?>
\layout Code
<methodCall>
\layout Code
<methodName>system.login</methodName>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>server_name</name>
\layout Code
<value><string>my.host.name</string></value>
\layout Code
</member>
\layout Code
<member><name>username</name>
\layout Code
<value><string>bubba</string></value>
\layout Code
</member>
\layout Code
<member><name>password</name>
\layout Code
<value><string>gump</string></value>
\layout Code
</member> </struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodCall>
\layout Standard
And the same in SOAP:
\layout Code
<?xml version="1.0"?>
\layout Code
<SOAP-ENV:Envelope
\layout Code
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.
org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:si="http://soapi
nterop.org/xsd"
\layout Code
xmlns:ns6="http://soapinterop.org" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.o
rg/soap/encoding/">
\layout Code
<SOAP-ENV:Body> <ns6:system_login>
\layout Code
<server_name xsi:type=":string">my.host.name</server_name>
\layout Code
<username xsi:type=":string">bubba</username>
\layout Code
<password xsi:type=":string">gump</password>
\layout Code
</ns6:system_login>
\layout Code
</SOAP-ENV:Body>
\layout Code
</SOAP-ENV:Envelope>
\layout Standard
The same style of packet would be required for a user/client login.
A successful login should yield the following reply:
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>sessionid</name>
\layout Code
<value><string>cf5c5534307562fc57915608377db007</string></value>
\layout Code
</member>
\layout Code
<member><name>kp3</name>
\layout Code
<value><string>2fe54daa11c8d52116788aa3f93cb70e</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodResponse>
\layout Standard
And a failed login:
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>GOAWAY</name>
\layout Code
<value><string>XOXO</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodResponse>
\layout Standard
eqweqw
\layout Subsubsection
system.logout
\layout Standard
Logout:
\layout Code
<?xml version="1.0"?>
\layout Code
<methodCall>
\layout Code
<methodName>system.logout</methodName>
\layout Code
<params> <param>
\layout Code
<value><struct>
\layout Code
<member><name>sessionid</name>
\layout Code
<value><string>ea35cac53d2c12bd05caecd97304478a</string></value>
\layout Code
</member>
\layout Code
<member><name>kp3</name>
\layout Code
<value><string>4f2b256e0da4e7cbbebaac9f1fc8ca4a</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodCall>
\layout Standard
Logout worked:
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>GOODBYE</name>
\layout Code
<value><string>XOXO</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodResponse>
\layout Section
Business layer requests
\layout Standard
Once a successful login return packet has been received and sessionid/kp3
have been extracted, every subsequent packet sent to the phpgroupware server
must be preceded by an Authorization header.
Here is a sample header:
\layout Code
POST /phpgroupware/xmlrpc.php HTTP/1.0
\layout Code
User-Agent: PHP XMLRPC 1.0
\layout Code
Host: my.local.host
\layout Code
Authorization: Basic ZDgxNDIyZDRkYjg5NDEyNGNiMzZlMDhhZTdlYzAxZmY6NTU3YzkyYjBmNGE
4ZDVlOTUzMzI2YmU2OTQyNjM3YjQ=
\layout Code
Content-Type: text/xml
\layout Code
Content-Length: 875
\layout Standard
The longish string is a base64 encoding of the $sessionid .
':' .
$kp3.
For now this is our only supported authentication method.
Additional methods would probably also affect the methodCalls.
This is certainly open to discussion.
Following is a typical request for some contact data:
\layout Code
<?xml version="1.0"?>
\layout Code
<methodCall>
\layout Code
<methodName>addressbook.boaddressbook.read_entries</methodName>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>start</name>
\layout Code
<value><string>1</string></value>
\layout Code
</member>
\layout Code
<member><name>limit</name>
\layout Code
<value><string>5</string></value>
\layout Code
</member>
\layout Code
<member><name>fields</name>
\layout Code
<value><struct>
\layout Code
<member><name>n_given</name>
\layout Code
<value><string>n_given</string></value>
\layout Code
</member>
\layout Code
<member><name>n_family</name>
\layout Code
<value><string>n_family</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</member>
\layout Code
<member><name>query</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>filter</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>sort</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>order</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodCall>
\layout Standard
Successful response:
\layout Code
<?xml version="1.0"?>
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><struct>
\layout Code
<member><name>0</name>
\layout Code
<value><struct>
\layout Code
<member><name>id</name>
\layout Code
<value><string>1</string></value>
\layout Code
</member>
\layout Code
<member><name>lid</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>tid</name>
\layout Code
<value><string>n</string></value>
\layout Code
</member>
\layout Code
<member><name>owner</name>
\layout Code
<value><string>500</string></value>
\layout Code
</member>
\layout Code
<member><name>access</name>
\layout Code
<value><string>private</string></value>
\layout Code
</member>
\layout Code
<member><name>cat_id</name>
\layout Code
<value><string>1</string></value>
\layout Code
</member>
\layout Code
<member><name>n_given</name>
\layout Code
<value><string>Alan</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</member>
\layout Code
<member><name>1</name>
\layout Code
<value><struct>
\layout Code
<member><name>id</name>
\layout Code
<value><string>2</string></value>
\layout Code
</member>
\layout Code
<member><name>lid</name>
\layout Code
<value><string></string></value>
\layout Code
</member>
\layout Code
<member><name>tid</name>
\layout Code
<value><string>n</string></value>
\layout Code
</member>
\layout Code
<member><name>owner</name>
\layout Code
<value><string>500</string></value>
\layout Code
</member>
\layout Code
<member><name>access</name>
\layout Code
<value><string>private</string></value>
\layout Code
</member>
\layout Code
<member><name>cat_id</name>
\layout Code
<value><string>1</string></value>
\layout Code
</member>
\layout Code
<member><name>n_given</name>
\layout Code
<value><string>Andy</string></value>
\layout Code
</member>
\layout Code
</struct></value>
\layout Code
</member>
\layout Code
...
\layout Standard
Unauthorized access attempt returns:
\layout Code
<methodResponse>
\layout Code
<params>
\layout Code
<param>
\layout Code
<value><string>UNAUTHORIZED</string></value>
\layout Code
</param>
\layout Code
</params>
\layout Code
</methodResponse>
\layout Section
More to come...
\layout Standard
Documenting every single call will be difficult, but should be done.
In leiu of this, please see the class.bo{APPNAME}.inc.php files in each applicatio
n/inc directory in the phpgroupware cvs.
In this file will be a list_methods() function, which returns the information
to the server about input/output structure for each call.
If the file does not have this function, then it is not yet workable via
this interface.
As for the actual functions, they are also in this file.
Generally, they will all accept associative array input and return same,
but not always.
This code is in flux, have fun.
\the_end

Binary file not shown.

View File

@ -0,0 +1,603 @@
%!PS-Adobe-2.0
%%Creator: dvipsk 5.86 p1.5d Copyright 1996-2001 ASCII Corp.(www-ptex@ascii.co.jp)
%%based on dvipsk 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com)
%%Title: phpgw_server.dvi
%%Pages: 8
%%PageOrder: Ascend
%%BoundingBox: 0 0 612 792
%%DocumentFonts: Helvetica-Bold Times-Roman Courier Times-Italic
%%EndComments
%DVIPSWebPage: (www.radicaleye.com)
%DVIPSCommandLine: dvips -t letter -o phpgw_server.ps phpgw_server.dvi
%DVIPSParameters: dpi=600, compressed
%DVIPSSource: TeX output 2001.09.03:2156
%%BeginProcSet: texc.pro
%!
/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3
1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx
0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx
sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{
rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp
gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B
/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{
/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{
A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy
get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse}
ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp
fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17
{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add
chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{
1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop}
forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
/dir 0 def/dyy{/dir 0 def}B/dyt{/dir 1 def}B/dty{/dir 2 def}B/dtt{/dir 3
def}B/p{dir 2 eq{-90 rotate show 90 rotate}{dir 3 eq{-90 rotate show 90
rotate}{show}ifelse}ifelse}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0
N/Ry 0 N/V{}B/RV/v{/Ry X/Rx X V}B statusdict begin/product where{pop
false[(Display)(NeXT)(LaserWriter 16/600)]{A length product length le{A
length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}
forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{
BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat
{BDot}imagemask grestore}}ifelse B/QV{gsave newpath transform round exch
round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0
rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B
/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}
B/g{0 M}B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p
-3 w}B/n{p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{
0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
%%EndProcSet
%%BeginProcSet: 8r.enc
% @@psencodingfile@{
% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry",
% version = "0.6",
% date = "1 July 1998",
% filename = "8r.enc",
% email = "tex-fonts@@tug.org",
% docstring = "Encoding for TrueType or Type 1 fonts
% to be used with TeX."
% @}
%
% Idea is to have all the characters normally included in Type 1 fonts
% available for typesetting. This is effectively the characters in Adobe
% Standard Encoding + ISO Latin 1 + extra characters from Lucida.
%
% Character code assignments were made as follows:
%
% (1) the Windows ANSI characters are almost all in their Windows ANSI
% positions, because some Windows users cannot easily reencode the
% fonts, and it makes no difference on other systems. The only Windows
% ANSI characters not available are those that make no sense for
% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen
% (173). quotesingle and grave are moved just because it's such an
% irritation not having them in TeX positions.
%
% (2) Remaining characters are assigned arbitrarily to the lower part
% of the range, avoiding 0, 10 and 13 in case we meet dumb software.
%
% (3) Y&Y Lucida Bright includes some extra text characters; in the
% hopes that other PostScript fonts, perhaps created for public
% consumption, will include them, they are included starting at 0x12.
%
% (4) Remaining positions left undefined are for use in (hopefully)
% upward-compatible revisions, if someday more characters are generally
% available.
%
% (5) hyphen appears twice for compatibility with both
% ASCII and Windows.
%
/TeXBase1Encoding [
% 0x00 (encoded characters from Adobe Standard not in Windows 3.1)
/.notdef /dotaccent /fi /fl
/fraction /hungarumlaut /Lslash /lslash
/ogonek /ring /.notdef
/breve /minus /.notdef
% These are the only two remaining unencoded characters, so may as
% well include them.
/Zcaron /zcaron
% 0x10
/caron /dotlessi
% (unusual TeX characters available in, e.g., Lucida Bright)
/dotlessj /ff /ffi /ffl
/.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef
% very contentious; it's so painful not having quoteleft and quoteright
% at 96 and 145 that we move the things normally found there to here.
/grave /quotesingle
% 0x20 (ASCII begins)
/space /exclam /quotedbl /numbersign
/dollar /percent /ampersand /quoteright
/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
% 0x30
/zero /one /two /three /four /five /six /seven
/eight /nine /colon /semicolon /less /equal /greater /question
% 0x40
/at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
% 0x50
/P /Q /R /S /T /U /V /W
/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
% 0x60
/quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
% 0x70
/p /q /r /s /t /u /v /w
/x /y /z /braceleft /bar /braceright /asciitilde
/.notdef % rubout; ASCII ends
% 0x80
/.notdef /.notdef /quotesinglbase /florin
/quotedblbase /ellipsis /dagger /daggerdbl
/circumflex /perthousand /Scaron /guilsinglleft
/OE /.notdef /.notdef /.notdef
% 0x90
/.notdef /.notdef /.notdef /quotedblleft
/quotedblright /bullet /endash /emdash
/tilde /trademark /scaron /guilsinglright
/oe /.notdef /.notdef /Ydieresis
% 0xA0
/.notdef % nobreakspace
/exclamdown /cent /sterling
/currency /yen /brokenbar /section
/dieresis /copyright /ordfeminine /guillemotleft
/logicalnot
/hyphen % Y&Y (also at 45); Windows' softhyphen
/registered
/macron
% 0xD0
/degree /plusminus /twosuperior /threesuperior
/acute /mu /paragraph /periodcentered
/cedilla /onesuperior /ordmasculine /guillemotright
/onequarter /onehalf /threequarters /questiondown
% 0xC0
/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
/Egrave /Eacute /Ecircumflex /Edieresis
/Igrave /Iacute /Icircumflex /Idieresis
% 0xD0
/Eth /Ntilde /Ograve /Oacute
/Ocircumflex /Otilde /Odieresis /multiply
/Oslash /Ugrave /Uacute /Ucircumflex
/Udieresis /Yacute /Thorn /germandbls
% 0xE0
/agrave /aacute /acircumflex /atilde
/adieresis /aring /ae /ccedilla
/egrave /eacute /ecircumflex /edieresis
/igrave /iacute /icircumflex /idieresis
% 0xF0
/eth /ntilde /ograve /oacute
/ocircumflex /otilde /odieresis /divide
/oslash /ugrave /uacute /ucircumflex
/udieresis /yacute /thorn /ydieresis
] def
%%EndProcSet
%%BeginProcSet: texps.pro
%!
TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2
index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll
exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics
exch def dict begin 0 1 255{exch dup type/integertype ne{pop pop 1 sub
dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def}
ifelse}for Metrics/Metrics currentdict end def[2 index currentdict end
definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup
sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll
mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[
exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if}
forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def
end
%%EndProcSet
%%BeginProcSet: special.pro
%!
TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N
/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N
/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N
/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{
/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho
X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B
/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{
/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known
{userdict/md get type/dicttype eq{userdict begin md length 10 add md
maxlength ge{/md md dup length 20 add dict copy def}if end md begin
/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S
atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{
itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll
transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll
curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf
pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}
if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1
-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3
get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip
yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub
neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{
noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop
90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get
neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr
1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr
2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4
-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S
TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{
Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale
}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState
save N userdict maxlength dict begin/magscale true def normalscale
currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts
/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x
psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx
psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub
TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{
psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2
roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath
moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict
begin/SpecialSave save N gsave normalscale currentpoint TR
@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{
CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto
closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx
sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR
}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse
CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury
lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N
/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end}
repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N
/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX
currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY
moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X
/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0
1 startangle endangle arc savematrix setmatrix}N end
%%EndProcSet
%%BeginProcSet: color.pro
%!
TeXDict begin/setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop
setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll
}repeat setrgbcolor pop}ifelse}B}ifelse/TeXcolorcmyk{setcmykcolor}def
/TeXcolorrgb{setrgbcolor}def/TeXcolorgrey{setgray}def/TeXcolorgray{
setgray}def/TeXcolorhsb{sethsbcolor}def/currentcmykcolor where{pop}{
/currentcmykcolor{currentrgbcolor 10}B}ifelse/DC{exch dup userdict exch
known{pop pop}{X}ifelse}B/GreenYellow{0.15 0 0.69 0 setcmykcolor}DC
/Yellow{0 0 1 0 setcmykcolor}DC/Goldenrod{0 0.10 0.84 0 setcmykcolor}DC
/Dandelion{0 0.29 0.84 0 setcmykcolor}DC/Apricot{0 0.32 0.52 0
setcmykcolor}DC/Peach{0 0.50 0.70 0 setcmykcolor}DC/Melon{0 0.46 0.50 0
setcmykcolor}DC/YellowOrange{0 0.42 1 0 setcmykcolor}DC/Orange{0 0.61
0.87 0 setcmykcolor}DC/BurntOrange{0 0.51 1 0 setcmykcolor}DC
/Bittersweet{0 0.75 1 0.24 setcmykcolor}DC/RedOrange{0 0.77 0.87 0
setcmykcolor}DC/Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC/Maroon{0 0.87
0.68 0.32 setcmykcolor}DC/BrickRed{0 0.89 0.94 0.28 setcmykcolor}DC/Red{
0 1 1 0 setcmykcolor}DC/OrangeRed{0 1 0.50 0 setcmykcolor}DC/RubineRed{
0 1 0.13 0 setcmykcolor}DC/WildStrawberry{0 0.96 0.39 0 setcmykcolor}DC
/Salmon{0 0.53 0.38 0 setcmykcolor}DC/CarnationPink{0 0.63 0 0
setcmykcolor}DC/Magenta{0 1 0 0 setcmykcolor}DC/VioletRed{0 0.81 0 0
setcmykcolor}DC/Rhodamine{0 0.82 0 0 setcmykcolor}DC/Mulberry{0.34 0.90
0 0.02 setcmykcolor}DC/RedViolet{0.07 0.90 0 0.34 setcmykcolor}DC
/Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC/Lavender{0 0.48 0 0
setcmykcolor}DC/Thistle{0.12 0.59 0 0 setcmykcolor}DC/Orchid{0.32 0.64 0
0 setcmykcolor}DC/DarkOrchid{0.40 0.80 0.20 0 setcmykcolor}DC/Purple{
0.45 0.86 0 0 setcmykcolor}DC/Plum{0.50 1 0 0 setcmykcolor}DC/Violet{
0.79 0.88 0 0 setcmykcolor}DC/RoyalPurple{0.75 0.90 0 0 setcmykcolor}DC
/BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC/Periwinkle{0.57 0.55 0 0
setcmykcolor}DC/CadetBlue{0.62 0.57 0.23 0 setcmykcolor}DC
/CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC/MidnightBlue{0.98 0.13 0
0.43 setcmykcolor}DC/NavyBlue{0.94 0.54 0 0 setcmykcolor}DC/RoyalBlue{1
0.50 0 0 setcmykcolor}DC/Blue{1 1 0 0 setcmykcolor}DC/Cerulean{0.94 0.11
0 0 setcmykcolor}DC/Cyan{1 0 0 0 setcmykcolor}DC/ProcessBlue{0.96 0 0 0
setcmykcolor}DC/SkyBlue{0.62 0 0.12 0 setcmykcolor}DC/Turquoise{0.85 0
0.20 0 setcmykcolor}DC/TealBlue{0.86 0 0.34 0.02 setcmykcolor}DC
/Aquamarine{0.82 0 0.30 0 setcmykcolor}DC/BlueGreen{0.85 0 0.33 0
setcmykcolor}DC/Emerald{1 0 0.50 0 setcmykcolor}DC/JungleGreen{0.99 0
0.52 0 setcmykcolor}DC/SeaGreen{0.69 0 0.50 0 setcmykcolor}DC/Green{1 0
1 0 setcmykcolor}DC/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC
/PineGreen{0.92 0 0.59 0.25 setcmykcolor}DC/LimeGreen{0.50 0 1 0
setcmykcolor}DC/YellowGreen{0.44 0 0.74 0 setcmykcolor}DC/SpringGreen{
0.26 0 0.76 0 setcmykcolor}DC/OliveGreen{0.64 0 0.95 0.40 setcmykcolor}
DC/RawSienna{0 0.72 1 0.45 setcmykcolor}DC/Sepia{0 0.83 1 0.70
setcmykcolor}DC/Brown{0 0.81 1 0.60 setcmykcolor}DC/Tan{0.14 0.42 0.56 0
setcmykcolor}DC/Gray{0 0 0 0.50 setcmykcolor}DC/Black{0 0 0 1
setcmykcolor}DC/White{0 0 0 0 setcmykcolor}DC end
%%EndProcSet
TeXDict begin 40258431 52099146 1000 600 600 (phpgw_server.dvi)
@start /Fa 134[ 37 3[ 42 23 1[ 32 1[ 42 42 2[ 23 3[ 42
42 1[ 37 42 2[ 42 8[ 51 69 3[ 42 51 1[ 51 60 1[ 69 46
4[ 60 3[ 55 1[ 51 8[ 42 42 42 42 42 42 42 42 1[ 23 1[ 28
45[{ TeXBase1Encoding ReEncodeFont} 33 83.022 /Times-Italic
rf /Fb 133[ 45 45 45 45 45 45 45 45 45 45 45 45 45 45
45 45 45 45 45 45 45 45 45 45 45 45 1[ 45 4[ 45 45 45
45 45 45 45 45 45 45 45 45 45 45 45 2[ 45 45 45 1[ 45
45 45 45 45 1[ 45 45 45 45 1[ 45 45 45 45 45 45 45 45
45 45 45 45 45 45 10[ 45 34[{ TeXBase1Encoding ReEncodeFont} 69
74.7198 /Courier rf /Fc 134[ 55 3[ 61 33 55 3[ 61 61
89 28 2[ 28 1[ 61 1[ 55 50[ 55 55 2[ 28 46[{
TeXBase1Encoding ReEncodeFont} 14 99.6264 /Helvetica-Bold
rf /Fd 130[ 40 1[ 40 37 42 42 60 42 42 23 32 28 42 42
42 42 65 23 42 1[ 23 42 42 28 37 42 37 42 37 1[ 42 6[ 60
78 1[ 60 51 46 55 1[ 46 60 60 74 51 2[ 28 60 60 46 51
60 55 55 60 6[ 23 3[ 42 1[ 42 42 3[ 23 21 28 21 2[ 28
28 28 2[ 42 32[ 46 46 2[{ TeXBase1Encoding ReEncodeFont} 62
83.022 /Times-Roman rf /Fe 138[ 73 40 4[ 73 73 4[ 33
73 73 1[ 66 73 66 1[ 66 20[ 73 26[ 66 2[ 33 46[{
TeXBase1Encoding ReEncodeFont} 14 119.552 /Helvetica-Bold
rf /Ff 134[ 80 2[ 80 88 48 80 56 88 1[ 88 88 128 40 2[ 40
3[ 80 1[ 80 1[ 80 13[ 96 5[ 120 10[ 104 14[ 80 80 80
2[ 40 46[{ TeXBase1Encoding ReEncodeFont} 22 143.462
/Helvetica-Bold rf /Fg 134[ 115 3[ 126 69 1[ 80 1[ 126
126 2[ 57 3[ 126 126 1[ 115 126 2[ 115 8[ 138 195 3[ 138
149 1[ 138 161 1[ 172 126 4[ 161 3[ 149 1[ 149 17[ 57
1[ 69 45[{ TeXBase1Encoding ReEncodeFont} 25 206.584
/Helvetica-Bold rf end
%%EndProlog
%%BeginSetup
%%Feature: *Resolution 600dpi
TeXDict begin
%%BeginPaperSize: Letter
letter
%%EndPaperSize
%%EndSetup
%%Page: 1 1
1 0 bop Black 0 TeXcolorgray Black Black Fg 579 647 a(phpGr) l(oupW) -8
b(are) 58 b(XML-RPC/SO) -10 b(AP) 1497 915 y(Methodolog) r(y) p
Ff -2 1382 a(1.) 39 b(System) f(le) n(vel) h(request) n(s) p
Fe -2 1710 a(1.1.) 34 b(Login) g(and) g(authentica) r(tion) p
Fd 396 1878 a(Authenticatio) n(n) 20 b(for) g(user) g(logins) g(is) h
(hand) n(led) g(intern) n(ally) g(no) e(dif) n(feren) n(tly) h(than) g
(for) g(the) g(typical) g(php) n(Group) n(W) -7 b(are) 396
1986 y(login) 20 b(via) g(web) g(bro) n(wser) -7 b(.) 21
b(Serv) o(er) e(logins,) h(added) f(for) h(XML-RPC) g(and) g(SO) m(AP)
-9 b(,) 21 b(are) f(only) f(slightly) h(dif) n(fer) n(ent.) g(F) o(or)
396 2094 y(either) g(proto) n(col,) g(user) g(and) g(serv) o(er) f
(login) h(and) f(authenticatio) n(n) i(and) e(subsequen) n(t) i(requ) n
(ests) h(are) e(hand) n(led) g(by) g(their) 396 2202
y(respecti) n(v) o(e) f(serv) o(er) h(app) n(s,) h(xmlrpc) n(.php) f
(and) f(soap.ph) n(p.) h(A) h(serv) o(er) e(is) i(identi\002ed) f(by) f
(a) i(custom) f(HTTP) g(header) -5 b(,) 396 2309 y(without) 20
b(which) f(a) i(norm) n(al) g(user) f(login) f(will) i(be) g(und) n
(ertak) o(en.) 396 2459 y(A) g(client) f(or) g(serv) o(er) f(sends) i
(the) f(appr) n(opriate) g(XML-RPC) g(or) g(SO) m(AP) h(pack) o(et) f
(contain) n(ing) g(host,) g(user) m(,) g(and) f(passw) o(ord) 396
2567 y(inform) n(ation) h(to) g(the) h(php) n(gw) f(serv) o(er) -5
b(.) 20 b(The) g(serv) o(er) f(then) h(assigns) g(a) h(sessionid) f
(and) g(k) o(e) o(y) -5 b(,) 19 b(which) g(is) j(retur) n(ned) e(to) g
(the) 396 2675 y(client) g(in) h(the) f(appro) n(priate) g(form) n(at.)
396 2824 y(Our) g(curren) n(t) h(method) e(for) g(authenticatin) n(g) i
(requ) n(ests) g(after) f(successful) g(login) g(is) h(via) f(the) g
(Author) n(ization:) g(Basic) 396 2932 y(HTTP) g(header) f(to) i(be) f
(sent) g(by) g(the) g(client) g(or) f(requesting) g(serv) o(er) -7
b(.) 21 b(The) f(form) n(at) h(of) f(this) g(header) f(is) i(a) g
(base64) e(encod) n(ing) 396 3040 y(of) h(the) g(assigned) g(sessionid)
g(and) g(kp3) f(v) n(ariables,) g(seperated) h(by) f(a) i(':'.) 396
3189 y(Further) e(security) h(may) g(be) g(obtain) n(ed) h(by) e(using)
h(SSL) h(on) f(the) g(client) g(and) g(serv) o(er) -7
b(.) 21 b(In) f(the) g(future,) f(we) i(may) 396 3297
y(encryp) n(t/descrypt) e(the) i(data) f(on) f(either) h(end,) g(or) g
(at) g(least) h(pro) o(v) n(ide) f(this) h(as) g(an) f(option) n(.) h
(The) f(sessionid) g(and) f(k) o(e) o(y) 396 3405 y(v) n(ariables) h
(will) h(mak) o(e) e(this) i(possible,) f(and) f(relati) n(v) o(ely) g
(secure.) p Fc 396 3693 a(1.1.1.) 28 b(syst) r(em.logi) n(n) p
Fd 396 3850 a(The) 20 b(\002rst) h(reque) n(st) h(a) e(client) g(will) h
(mak) o(e) f(is) h(the) f(system.login) f(method) n(.) i(Here) f(is) h
(a) g(sample) f(of) g(a) g(serv) o(er) f(login) h(pack) o(et) 396
3958 y(in) h(XML-RPC:) p Fb 396 4138 a(<?xml) 44 b(version="1.) n(0"?>)
396 4236 y(<methodCall) n(>) 396 4333 y(<methodName) n(>system.logi) n
(n</methodNam) n(e>) 396 4430 y(<params>) 396 4527 y(<param>) 396
4624 y(<value><str) n(uct>) 396 4721 y(<member><na) n(me>server_na) n
(me</name>) 396 4818 y(<value><str) n(ing>my.host.) n(name</string) n
(></value>) p Black Fa 3842 5278 a(1) p Black 90 rotate
dyy eop
%%Page: 2 2
2 1 bop Black 0 TeXcolorgray Black Fa 2326 67 a(php) n(Gr) l(oupW) -8
b(ar) m(e) 20 b(XML-RPC/SO) -5 b(AP) 20 b(Methodo) n(lo) o(gy) p
Black Fb 396 579 a(</member>) 396 676 y(<member><na) n(me>username<) n
(/name>) 396 773 y(<value><str) n(ing>bubba</s) n(tring></valu) n(e>)
396 870 y(</member>) 396 967 y(<member><na) n(me>password<) n(/name>)
396 1065 y(<value><str) n(ing>gump</st) n(ring></value) n(>) 396
1162 y(</member>) 44 b(</struc) n(t></value>) 396 1259
y(</param>) 396 1356 y(</params>) 396 1453 y(</methodCal) n(l>) p
Fd 396 1741 a(And) 20 b(the) g(same) h(in) f(SO) m(AP:) p
Fb 396 1921 a(<?xml) 44 b(version="1.) n(0"?>) 396 2019
y(<SOAP-ENV:E) n(nvelope) 396 2116 y(xmlns:SOAP-) n(ENV="http://) n
(schemas.xmls) n(oap.org/soap) n(/envelope/") f(xmlns:xsi=") n
(http://www.w) n(3.org/1999/X) n(MLSchema-) 396 2213
y(instance") h(xmlns:x) n(sd="http://w) n(ww.w3.org/19) n(99/XMLSchema)
n(") h(xmlns:SOAP) n(-ENC="http:) n(//schemas.xm) n(lsoap.org/so) n
(ap/encoding/) n(") g(xmlns:si=") n(http://soapi) n(nterop.org/x) n
(sd") 396 2310 y(xmlns:ns6=") n(http://soapi) n(nterop.org") e
(SOAP-ENV:enc) n(odingStyle=") n(http://sche) n(mas.xmlsoap.) n
(org/soap/enc) n(oding/">) 396 2407 y(<SOAP-ENV:B) n(ody>) i(<ns6:sy) n
(stem_login>) 396 2504 y(<server_nam) n(e) g(xsi:type=") n
(:string">my.) n(host.name</s) n(erver_name>) 396 2601
y(<username) f(xsi:typ) n(e=":string">) n(bubba</usern) n(ame>) 396
2698 y(<password) g(xsi:typ) n(e=":string">) n(gump</passwo) n(rd>) 396
2796 y(</ns6:syste) n(m_login>) 396 2893 y(</SOAP-ENV:) n(Body>) 396
2990 y(</SOAP-ENV:) n(Envelope>) p Fd 396 3278 a(The) 20
b(same) g(style) h(of) f(pack) o(et) g(w) o(ould) f(be) h(requir) n(ed)
h(for) e(a) i(user/client) e(login.) h(A) g(successful) g(login) g
(should) f(yield) h(the) 396 3386 y(follo) n(wing) f(reply) n(:) p
Fb 396 3566 a(<methodResp) n(onse>) 396 3663 y(<params>) 396
3760 y(<param>) 396 3857 y(<value><str) n(uct>) 396 3955
y(<member><na) n(me>sessionid) n(</name>) 396 4052 y(<value><str) n
(ing>cf5c5534) n(307562fc5791) n(5608377db007) n(</string></v) n(alue>)
396 4149 y(</member>) 396 4246 y(<member><na) n(me>kp3</name) n(>) 396
4343 y(<value><str) n(ing>2fe54daa) n(11c8d5211678) n(8aa3f93cb70e) n
(</string></v) n(alue>) 396 4440 y(</member>) 396 4537
y(</struct></) n(value>) 396 4635 y(</param>) 396 4732
y(</params>) 396 4829 y(</methodRes) n(ponse>) p Black
Fa 3842 5278 a(2) p Black 90 rotate dyy eop
%%Page: 3 3
3 2 bop Black 0 TeXcolorgray Black Fa 2326 67 a(php) n(Gr) l(oupW) -8
b(ar) m(e) 20 b(XML-RPC/SO) -5 b(AP) 20 b(Methodo) n(lo) o(gy) p
Black Fd 396 770 a(And) g(a) h(f) o(ailed) f(login) n(:) p
Fb 396 950 a(<methodResp) n(onse>) 396 1047 y(<params>) 396
1144 y(<param>) 396 1241 y(<value><str) n(uct>) 396 1339
y(<member><na) n(me>GOAWAY</n) n(ame>) 396 1436 y(<value><str) n
(ing>XOXO</st) n(ring></value) n(>) 396 1533 y(</member>) 396
1630 y(</struct></) n(value>) 396 1727 y(</param>) 396
1824 y(</params>) 396 1921 y(</methodRes) n(ponse>) p
Fd 396 2209 a(eqweqw) p Fc 396 2547 a(1.1.2.) 28 b(syst) r(em.logou) n
(t) p Fd 396 2704 a(Logou) n(t:) p Fb 396 2884 a(<?xml) 44
b(version="1.) n(0"?>) 396 2982 y(<methodCall) n(>) 396
3079 y(<methodName) n(>system.logo) n(ut</methodNa) n(me>) 396
3176 y(<params>) g(<param>) 396 3273 y(<value><str) n(uct>) 396
3370 y(<member><na) n(me>sessionid) n(</name>) 396 3467
y(<value><str) n(ing>ea35cac5) n(3d2c12bd05ca) n(ecd97304478a) n
(</string></v) n(alue>) 396 3564 y(</member>) 396 3662
y(<member><na) n(me>kp3</name) n(>) 396 3759 y(<value><str) n
(ing>4f2b256e) n(0da4e7cbbeba) n(ac9f1fc8ca4a) n(</string></v) n(alue>)
396 3856 y(</member>) 396 3953 y(</struct></) n(value>) 396
4050 y(</param>) 396 4147 y(</params>) 396 4244 y(</methodCal) n(l>) p
Fd 396 4532 a(Logou) n(t) 21 b(w) o(ork) o(ed) n(:) p
Fb 396 4713 a(<methodResp) n(onse>) 396 4810 y(<params>) p
Black Fa 3842 5278 a(3) p Black 90 rotate dyy eop
%%Page: 4 4
4 3 bop Black 0 TeXcolorgray Black Fa 2326 67 a(php) n(Gr) l(oupW) -8
b(ar) m(e) 20 b(XML-RPC/SO) -5 b(AP) 20 b(Methodo) n(lo) o(gy) p
Black Fb 396 579 a(<param>) 396 676 y(<value><str) n(uct>) 396
773 y(<member><na) n(me>GOODBYE</) n(name>) 396 870 y(<value><str) n
(ing>XOXO</st) n(ring></value) n(>) 396 967 y(</member>) 396
1065 y(</struct></) n(value>) 396 1162 y(</param>) 396
1259 y(</params>) 396 1356 y(</methodRes) n(ponse>) p
Ff -2 2079 a(2.) 39 b(Busines) n(s) h(la) m(y) o(er) f(requ) n(ests) p
Fd 396 2259 a(Once) 20 b(a) h(successful) f(login) f(return) g(pack) o
(et) h(has) g(been) g(recei) n(v) o(e) n(d) g(and) g(sessionid/kp3) f
(ha) n(v) o(e) g(been) h(e) o(xtracte) n(d,) g(e) n(v) o(ery) 396
2367 y(subsequen) n(t) h(pack) m(et) g(sent) f(to) g(the) g(php) n
(group) n(w) o(are) g(serv) o(er) f(must) h(be) g(prec) n(eded) g(by) f
(an) h(Autho) n(rization) f(header) -5 b(.) 19 b(Here) h(is) 396
2475 y(a) h(sample) f(heade) n(r:) p Fb 396 2655 a(POST) 44
b(/phpgroupwar) n(e/xmlrpc.php) f(HTTP/1.0) 396 2752
y(User-Agent:) g(PHP) i(XMLRPC) e(1.0) 396 2849 y(Host:) h(my.local.ho)
n(st) 396 2946 y(Authorizati) n(on:) h(Basic) f(ZDgxNDIy) n
(ZDRkYjg5NDEy) n(NGNiMzZlMDhh) n(ZTdlYzAxZmY6) n(NTU3YzkyYjB) n
(mNGE4ZDVlOTU) n(zMzI2YmU2OTQ) n(yNjM3YjQ=) 396 3044
y(Content-Typ) n(e:) h(text/xml) 396 3141 y(Content-Len) n(gth:) g(875)
p Fd 396 3429 a(The) 20 b(longish) f(string) h(is) h(a) g(base64) e
(encodin) n(g) h(of) g(the) h($sessionid) e(.) i(':') f(.) g($kp3) n(.)
h(F) o(or) f(no) n(w) f(this) i(is) g(our) f(only) f(suppo) n(rted) 396
3537 y(authentica) n(tion) h(method) n(.) h(Addition) n(al) g(metho) n
(ds) g(w) o(ould) f(pro) n(bably) f(also) i(af) n(fect) f(the) g(metho)
n(dCalls.) h(This) f(is) i(certain) n(ly) 396 3645 y(open) d(to) i
(discussion.) e(F) o(ollo) n(wing) g(is) i(a) g(typical) f(requ) n(est)
h(for) f(some) g(con) n(tact) h(data:) p Fb 396 3825
a(<?xml) 44 b(version="1.) n(0"?>) 396 3922 y(<methodCall) n(>) 396
4019 y(<methodName) n(>addressbook) n(.boaddressbo) n(ok.read_entr) n
(ies</methodN) n(ame>) 396 4116 y(<params>) 396 4213
y(<param>) 396 4310 y(<value><str) n(uct>) 396 4408 y(<member><na) n
(me>start</na) n(me>) 396 4505 y(<value><str) n(ing>1</strin) n
(g></value>) 396 4602 y(</member>) 396 4699 y(<member><na) n
(me>limit</na) n(me>) 396 4796 y(<value><str) n(ing>5</strin) n
(g></value>) p Black Fa 3842 5278 a(4) p Black 90 rotate
dyy eop
%%Page: 5 5
5 4 bop Black 0 TeXcolorgray Black Fa 2326 67 a(php) n(Gr) l(oupW) -8
b(ar) m(e) 20 b(XML-RPC/SO) -5 b(AP) 20 b(Methodo) n(lo) o(gy) p
Black Fb 396 579 a(</member>) 396 676 y(<member><na) n(me>fields</n) n
(ame>) 396 773 y(<value><str) n(uct>) 396 870 y(<member><na) n
(me>n_given</) n(name>) 396 967 y(<value><str) n(ing>n_given<) n
(/string></va) n(lue>) 396 1065 y(</member>) 396 1162
y(<member><na) n(me>n_family<) n(/name>) 396 1259 y(<value><str) n
(ing>n_family) n(</string></v) n(alue>) 396 1356 y(</member>) 396
1453 y(</struct></) n(value>) 396 1550 y(</member>) 396
1647 y(<member><na) n(me>query</na) n(me>) 396 1745 y(<value><str) n
(ing></string) n(></value>) 396 1842 y(</member>) 396
1939 y(<member><na) n(me>filter</n) n(ame>) 396 2036
y(<value><str) n(ing></string) n(></value>) 396 2133
y(</member>) 396 2230 y(<member><na) n(me>sort</nam) n(e>) 396
2327 y(<value><str) n(ing></string) n(></value>) 396
2424 y(</member>) 396 2522 y(<member><na) n(me>order</na) n(me>) 396
2619 y(<value><str) n(ing></string) n(></value>) 396
2716 y(</member>) 396 2813 y(</struct></) n(value>) 396
2910 y(</param>) 396 3007 y(</params>) 396 3104 y(</methodCal) n(l>) p
Fd 396 3393 a(Successful) g(respon) n(se:) p Fb 396 3573
a(<?xml) 44 b(version="1.) n(0"?>) 396 3670 y(<methodResp) n(onse>) 396
3767 y(<params>) 396 3864 y(<param>) 396 3961 y(<value><str) n(uct>) 396
4058 y(<member><na) n(me>0</name>) 396 4155 y(<value><str) n(uct>) 396
4253 y(<member><na) n(me>id</name>) 396 4350 y(<value><str) n
(ing>1</strin) n(g></value>) 396 4447 y(</member>) 396
4544 y(<member><na) n(me>lid</name) n(>) 396 4641 y(<value><str) n
(ing></string) n(></value>) 396 4738 y(</member>) 396
4835 y(<member><na) n(me>tid</name) n(>) p Black Fa 3842
5278 a(5) p Black 90 rotate dyy eop
%%Page: 6 6
6 5 bop Black 0 TeXcolorgray Black Fa 2326 67 a(php) n(Gr) l(oupW) -8
b(ar) m(e) 20 b(XML-RPC/SO) -5 b(AP) 20 b(Methodo) n(lo) o(gy) p
Black Fb 396 579 a(<value><str) n(ing>n</strin) n(g></value>) 396
676 y(</member>) 396 773 y(<member><na) n(me>owner</na) n(me>) 396
870 y(<value><str) n(ing>500</str) n(ing></value>) 396
967 y(</member>) 396 1065 y(<member><na) n(me>access</n) n(ame>) 396
1162 y(<value><str) n(ing>private<) n(/string></va) n(lue>) 396
1259 y(</member>) 396 1356 y(<member><na) n(me>cat_id</n) n(ame>) 396
1453 y(<value><str) n(ing>1</strin) n(g></value>) 396
1550 y(</member>) 396 1647 y(<member><na) n(me>n_given</) n(name>) 396
1745 y(<value><str) n(ing>Alan</st) n(ring></value) n(>) 396
1842 y(</member>) 396 1939 y(</struct></) n(value>) 396
2036 y(</member>) 396 2133 y(<member><na) n(me>1</name>) 396
2230 y(<value><str) n(uct>) 396 2327 y(<member><na) n(me>id</name>) 396
2424 y(<value><str) n(ing>2</strin) n(g></value>) 396
2522 y(</member>) 396 2619 y(<member><na) n(me>lid</name) n(>) 396
2716 y(<value><str) n(ing></string) n(></value>) 396
2813 y(</member>) 396 2910 y(<member><na) n(me>tid</name) n(>) 396
3007 y(<value><str) n(ing>n</strin) n(g></value>) 396
3104 y(</member>) 396 3202 y(<member><na) n(me>owner</na) n(me>) 396
3299 y(<value><str) n(ing>500</str) n(ing></value>) 396
3396 y(</member>) 396 3493 y(<member><na) n(me>access</n) n(ame>) 396
3590 y(<value><str) n(ing>private<) n(/string></va) n(lue>) 396
3687 y(</member>) 396 3784 y(<member><na) n(me>cat_id</n) n(ame>) 396
3882 y(<value><str) n(ing>1</strin) n(g></value>) 396
3979 y(</member>) 396 4076 y(<member><na) n(me>n_given</) n(name>) 396
4173 y(<value><str) n(ing>Andy</st) n(ring></value) n(>) 396
4270 y(</member>) 396 4367 y(</struct></) n(value>) 396
4464 y(</member>) 396 4561 y(...) p Fd 396 4850 a(Unautho) n(rized) g
(access) h(attempt) f(retur) n(ns:) p Black Fa 3840 5278
a(6) p Black 90 rotate dyy eop
%%Page: 7 7
7 6 bop Black 0 TeXcolorgray Black Fa 2326 67 a(php) n(Gr) l(oupW) -8
b(ar) m(e) 20 b(XML-RPC/SO) -5 b(AP) 20 b(Methodo) n(lo) o(gy) p
Black Fb 396 579 a(<methodResp) n(onse>) 396 676 y(<params>) 396
773 y(<param>) 396 870 y(<value><str) n(ing>UNAUTHOR) n(IZED</string) n
(></value>) 396 967 y(</param>) 396 1065 y(</params>) 396
1162 y(</methodRes) n(ponse>) p Ff -2 1719 a(3.) 39 b(More) g(to) g
(come) s(...) p Fd 396 1899 a(Documen) n(ting) 20 b(e) n(v) o(ery) f
(single) h(call) h(will) f(be) h(dif) n(\002cu) n(lt,) g(b) n(ut) f
(should) f(be) h(done.) f(In) h(leiu) h(of) e(this,) i(please) f(see) h
(the) 396 2007 y(class.bo{APPN) m(AME}.in) n(c.php) e(\002les) i(in) g
(each) f(app) n(lication/inc) g(directo) n(ry) g(in) h(the) f(php) n
(grou) n(pw) o(are) g(cvs.) g(In) g(this) h(\002le) 396
2115 y(will) g(be) f(a) h(list_metho) n(ds\(\)) f(functio) n(n,) g
(which) g(return) n(s) h(the) f(inform) n(ation) g(to) g(the) h(serv) o
(e) n(r) g(abou) n(t) g(input/o) n(utput) f(structur) n(e) 396
2222 y(for) g(each) g(call.) g(If) g(the) g(\002le) h(does) f(not) g
(ha) n(v) o(e) g(this) g(functio) n(n,) h(then) e(it) i(is) g(not) f
(yet) g(w) o(orkab) n(le) h(via) f(this) h(interf) o(ace.) e(As) i(for)
396 2330 y(the) f(actual) g(function) n(s,) h(the) o(y) e(are) i(also) f
(in) g(this) h(\002le.) g(Genera) n(lly) -5 b(,) 20 b(the) o(y) g(will)
h(all) f(accept) g(associati) n(v) o(e) g(array) f(input) h(and) 396
2438 y(return) f(same,) h(b) n(ut) h(not) e(al) o(w) o(ays.) i(This) f
(code) g(is) h(in) f(\003ux,) g(ha) n(v) o(e) f(fun.) p
Black Fa 3839 5278 a(7) p Black 90 rotate dyy eop
%%Page: 8 8
8 7 bop Black 0 TeXcolorgray Black Fa 2326 67 a(php) n(Gr) l(oupW) -8
b(ar) m(e) 20 b(XML-RPC/SO) -5 b(AP) 20 b(Methodo) n(lo) o(gy) p
Black Black 3842 5278 a(8) p Black 90 rotate dyy eop
%%Trailer
end
userdict /end-hook known{end-hook}if
%%EOF

View File

@ -0,0 +1,311 @@
<!doctype article public "-//OASIS//DTD DocBook V3.1//EN">
<article lang="en">
<!-- DocBook file was created by LyX 1.1
See http://www.lyx.org/ for more information -->
<artheader>
<title>
phpGroupWare XML-RPC/SOAP Methodology
</title>
<author>
Miles Lott
milosch@phpgroupware.org
</author>
<date>
August 23, 2001
</date>
<para>
additions made September 3, 2001.
</para>
<para>
This document is very preliminary, but describes a working system.
</para>
</artheader>
<sect1>
<title>
System level requests
</title>
<sect2>
<title>
Login and authentication
</title>
<para>
Authentication for user logins is handled internally no differently than for the typical phpGroupWare login via web browser. Server logins, added for XML-RPC and SOAP, are only slightly different. For either protocol, user and server login and authentication and subsequent requests are handled by their respective server apps, xmlrpc.php and soap.php. A server is identified by a custom HTTP header, without which a normal user login will be undertaken.
</para>
<para>
A client or server sends the appropriate XML-RPC or SOAP packet containing host, user, and password information to the phpgw server. The server then assigns a sessionid and key, which is returned to the client in the appropriate format.
</para>
<para>
Our current method for authenticating requests after successful login is via the Authorization: Basic HTTP header to be sent by the client or requesting server. The format of this header is a base64 encoding of the assigned sessionid and kp3 variables, seperated by a ':'.
</para>
<para>
Further security may be obtained by using SSL on the client and server. In the future, we may encrypt/descrypt the data on either end, or at least provide this as an option. The sessionid and key variables will make this possible, and relatively secure.
</para>
<sect3>
<title>
system.login
</title>
<para>
The first request a client will make is the system.login method. Here is a sample of a server login packet in XML-RPC:
</para>
<programlisting>
<![ CDATA [<?xml version="1.0"?>
]]><![ CDATA [<methodCall>
]]><![ CDATA [<methodName>system.login</methodName>
]]><![ CDATA [<params>
]]><![ CDATA [<param>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>server_name</name>
]]><![ CDATA [<value><string>my.host.name</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>username</name>
]]><![ CDATA [<value><string>bubba</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>password</name>
]]><![ CDATA [<value><string>gump</string></value>
]]><![ CDATA [</member> </struct></value>
]]><![ CDATA [</param>
]]><![ CDATA [</params>
]]><![ CDATA [</methodCall>
]]> </programlisting>
<para>
And the same in SOAP:
</para>
<programlisting>
<![ CDATA [<?xml version="1.0"?>
]]><![ CDATA [<SOAP-ENV:Envelope
]]><![ CDATA [xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:si="http://soapinterop.org/xsd"
]]><![ CDATA [xmlns:ns6="http://soapinterop.org" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
]]><![ CDATA [<SOAP-ENV:Body> <ns6:system_login>
]]><![ CDATA [<server_name xsi:type=":string">my.host.name</server_name>
]]><![ CDATA [<username xsi:type=":string">bubba</username>
]]><![ CDATA [<password xsi:type=":string">gump</password>
]]><![ CDATA [</ns6:system_login>
]]><![ CDATA [</SOAP-ENV:Body>
]]><![ CDATA [</SOAP-ENV:Envelope>
]]> </programlisting>
<para>
The same style of packet would be required for a user/client login. A successful login should yield the following reply:
</para>
<programlisting>
<![ CDATA [<methodResponse>
]]><![ CDATA [<params>
]]><![ CDATA [<param>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>sessionid</name>
]]><![ CDATA [<value><string>cf5c5534307562fc57915608377db007</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>kp3</name>
]]><![ CDATA [<value><string>2fe54daa11c8d52116788aa3f93cb70e</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [</struct></value>
]]><![ CDATA [</param>
]]><![ CDATA [</params>
]]><![ CDATA [</methodResponse>
]]> </programlisting>
<para>
And a failed login:
</para>
<programlisting>
<![ CDATA [<methodResponse>
]]><![ CDATA [<params>
]]><![ CDATA [<param>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>GOAWAY</name>
]]><![ CDATA [<value><string>XOXO</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [</struct></value>
]]><![ CDATA [</param>
]]><![ CDATA [</params>
]]><![ CDATA [</methodResponse>
]]> </programlisting>
<para>
eqweqw
</para>
</sect3>
<sect3>
<title>
system.logout
</title>
<para>
Logout:
</para>
<programlisting>
<![ CDATA [<?xml version="1.0"?>
]]><![ CDATA [<methodCall>
]]><![ CDATA [<methodName>system.logout</methodName>
]]><![ CDATA [<params> <param>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>sessionid</name>
]]><![ CDATA [<value><string>ea35cac53d2c12bd05caecd97304478a</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>kp3</name>
]]><![ CDATA [<value><string>4f2b256e0da4e7cbbebaac9f1fc8ca4a</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [</struct></value>
]]><![ CDATA [</param>
]]><![ CDATA [</params>
]]><![ CDATA [</methodCall>
]]> </programlisting>
<para>
Logout worked:
</para>
<programlisting>
<![ CDATA [<methodResponse>
]]><![ CDATA [<params>
]]><![ CDATA [<param>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>GOODBYE</name>
]]><![ CDATA [<value><string>XOXO</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [</struct></value>
]]><![ CDATA [</param>
]]><![ CDATA [</params>
]]><![ CDATA [</methodResponse>
]]> </programlisting>
</sect3>
</sect2>
</sect1>
<sect1>
<title>
Business layer requests
</title>
<para>
Once a successful login return packet has been received and sessionid/kp3 have been extracted, every subsequent packet sent to the phpgroupware server must be preceded by an Authorization header. Here is a sample header:
</para>
<programlisting>
<![ CDATA [POST /phpgroupware/xmlrpc.php HTTP/1.0
]]><![ CDATA [User-Agent: PHP XMLRPC 1.0
]]><![ CDATA [Host: my.local.host
]]><![ CDATA [Authorization: Basic ZDgxNDIyZDRkYjg5NDEyNGNiMzZlMDhhZTdlYzAxZmY6NTU3YzkyYjBmNGE4ZDVlOTUzMzI2YmU2OTQyNjM3YjQ=
]]><![ CDATA [Content-Type: text/xml
]]><![ CDATA [Content-Length: 875
]]> </programlisting>
<para>
The longish string is a base64 encoding of the &dollar;sessionid . ':' . &dollar;kp3. For now this is our only supported authentication method. Additional methods would probably also affect the methodCalls. This is certainly open to discussion. Following is a typical request for some contact data:
</para>
<programlisting>
<![ CDATA [<?xml version="1.0"?>
]]><![ CDATA [<methodCall>
]]><![ CDATA [<methodName>addressbook.boaddressbook.read_entries</methodName>
]]><![ CDATA [<params>
]]><![ CDATA [<param>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>start</name>
]]><![ CDATA [<value><string>1</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>limit</name>
]]><![ CDATA [<value><string>5</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>fields</name>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>n_given</name>
]]><![ CDATA [<value><string>n_given</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>n_family</name>
]]><![ CDATA [<value><string>n_family</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [</struct></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>query</name>
]]><![ CDATA [<value><string></string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>filter</name>
]]><![ CDATA [<value><string></string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>sort</name>
]]><![ CDATA [<value><string></string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>order</name>
]]><![ CDATA [<value><string></string></value>
]]><![ CDATA [</member>
]]><![ CDATA [</struct></value>
]]><![ CDATA [</param>
]]><![ CDATA [</params>
]]><![ CDATA [</methodCall>
]]> </programlisting>
<para>
Successful response:
</para>
<programlisting>
<![ CDATA [<?xml version="1.0"?>
]]><![ CDATA [<methodResponse>
]]><![ CDATA [<params>
]]><![ CDATA [<param>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>0</name>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>id</name>
]]><![ CDATA [<value><string>1</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>lid</name>
]]><![ CDATA [<value><string></string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>tid</name>
]]><![ CDATA [<value><string>n</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>owner</name>
]]><![ CDATA [<value><string>500</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>access</name>
]]><![ CDATA [<value><string>private</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>cat_id</name>
]]><![ CDATA [<value><string>1</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>n_given</name>
]]><![ CDATA [<value><string>Alan</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [</struct></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>1</name>
]]><![ CDATA [<value><struct>
]]><![ CDATA [<member><name>id</name>
]]><![ CDATA [<value><string>2</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>lid</name>
]]><![ CDATA [<value><string></string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>tid</name>
]]><![ CDATA [<value><string>n</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>owner</name>
]]><![ CDATA [<value><string>500</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>access</name>
]]><![ CDATA [<value><string>private</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>cat_id</name>
]]><![ CDATA [<value><string>1</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [<member><name>n_given</name>
]]><![ CDATA [<value><string>Andy</string></value>
]]><![ CDATA [</member>
]]><![ CDATA [</struct></value>
]]><![ CDATA [</member>
]]><![ CDATA [...
]]> </programlisting>
<para>
Unauthorized access attempt returns:
</para>
<programlisting>
<![ CDATA [<methodResponse>
]]><![ CDATA [<params>
]]><![ CDATA [<param>
]]><![ CDATA [<value><string>UNAUTHORIZED</string></value>
]]><![ CDATA [</param>
]]><![ CDATA [</params>
]]><![ CDATA [</methodResponse>
]]> </programlisting>
</sect1>
<sect1>
<title>
More to come...
</title>
<para>
Documenting every single call will be difficult, but should be done. In leiu of this, please see the class.bo&lcub;APPNAME&rcub;.inc.php files in each application/inc directory in the phpgroupware cvs. In this file will be a list_methods() function, which returns the information to the server about input/output structure for each call. If the file does not have this function, then it is not yet workable via this interface. As for the actual functions, they are also in this file. Generally, they will all accept associative array input and return same, but not always. This code is in flux, have fun.
</para>
</sect1>
</article>

View File

@ -0,0 +1,473 @@
phpGroupWare XML-RPC/SOAP Methodology
Miles Lott
milosch@phpgroupware.org
August 23, 2001
additions made September 3, 2001.
This document is very preliminary, but describes a working
system.
1 System level requests
1.1 Login and authentication
Authentication for user logins is handled internally no differently
than for the typical phpGroupWare login via web browser.
Server logins, added for XML-RPC and SOAP, are only slightly
different. For either protocol, user and server login and
authentication and subsequent requests are handled by their
respective server apps, xmlrpc.php and soap.php. A server
is identified by a custom HTTP header, without which a normal
user login will be undertaken.
A client or server sends the appropriate XML-RPC or SOAP
packet containing host, user, and password information to
the phpgw server. The server then assigns a sessionid and
key, which is returned to the client in the appropriate
format.
Our current method for authenticating requests after successful
login is via the Authorization: Basic HTTP header to be
sent by the client or requesting server. The format of this
header is a base64 encoding of the assigned sessionid and
kp3 variables, seperated by a ':'.
Further security may be obtained by using SSL on the client
and server. In the future, we may encrypt/descrypt the data
on either end, or at least provide this as an option. The
sessionid and key variables will make this possible, and
relatively secure.
1.1.1 system.login
The first request a client will make is the system.login
method. Here is a sample of a server login packet in XML-RPC:
<?xml version="1.0"?>
<methodCall>
<methodName>system.login</methodName>
<params>
<param>
<value><struct>
<member><name>server_name</name>
<value><string>my.host.name</string></value>
</member>
<member><name>username</name>
<value><string>bubba</string></value>
</member>
<member><name>password</name>
<value><string>gump</string></value>
</member> </struct></value>
</param>
</params>
</methodCall>
And the same in SOAP:
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:si="http://soapinterop.org/xsd"
xmlns:ns6="http://soapinterop.org" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body> <ns6:system_login>
<server_name xsi:type=":string">my.host.name</server_name>
<username xsi:type=":string">bubba</username>
<password xsi:type=":string">gump</password>
</ns6:system_login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The same style of packet would be required for a user/client
login. A successful login should yield the following reply:
<methodResponse>
<params>
<param>
<value><struct>
<member><name>sessionid</name>
<value><string>cf5c5534307562fc57915608377db007</string></value>
</member>
<member><name>kp3</name>
<value><string>2fe54daa11c8d52116788aa3f93cb70e</string></value>
</member>
</struct></value>
</param>
</params>
</methodResponse>
And a failed login:
<methodResponse>
<params>
<param>
<value><struct>
<member><name>GOAWAY</name>
<value><string>XOXO</string></value>
</member>
</struct></value>
</param>
</params>
</methodResponse>
eqweqw
1.1.2 system.logout
Logout:
<?xml version="1.0"?>
<methodCall>
<methodName>system.logout</methodName>
<params> <param>
<value><struct>
<member><name>sessionid</name>
<value><string>ea35cac53d2c12bd05caecd97304478a</string></value>
</member>
<member><name>kp3</name>
<value><string>4f2b256e0da4e7cbbebaac9f1fc8ca4a</string></value>
</member>
</struct></value>
</param>
</params>
</methodCall>
Logout worked:
<methodResponse>
<params>
<param>
<value><struct>
<member><name>GOODBYE</name>
<value><string>XOXO</string></value>
</member>
</struct></value>
</param>
</params>
</methodResponse>
2 Business layer requests
Once a successful login return packet has been received and
sessionid/kp3 have been extracted, every subsequent packet
sent to the phpgroupware server must be preceded by an Authorization
header. Here is a sample header:
POST /phpgroupware/xmlrpc.php HTTP/1.0
User-Agent: PHP XMLRPC 1.0
Host: my.local.host
Authorization: Basic ZDgxNDIyZDRkYjg5NDEyNGNiMzZlMDhhZTdlYzAxZmY6NTU3YzkyYjBmNGE4ZDVlOTUzMzI2YmU2OTQyNjM3YjQ=
Content-Type: text/xml
Content-Length: 875
The longish string is a base64 encoding of the $sessionid
. ':' . $kp3. For now this is our only supported authentication
method. Additional methods would probably also affect the
methodCalls. This is certainly open to discussion. Following
is a typical request for some contact data:
<?xml version="1.0"?>
<methodCall>
<methodName>addressbook.boaddressbook.read_entries</methodName>
<params>
<param>
<value><struct>
<member><name>start</name>
<value><string>1</string></value>
</member>
<member><name>limit</name>
<value><string>5</string></value>
</member>
<member><name>fields</name>
<value><struct>
<member><name>n_given</name>
<value><string>n_given</string></value>
</member>
<member><name>n_family</name>
<value><string>n_family</string></value>
</member>
</struct></value>
</member>
<member><name>query</name>
<value><string></string></value>
</member>
<member><name>filter</name>
<value><string></string></value>
</member>
<member><name>sort</name>
<value><string></string></value>
</member>
<member><name>order</name>
<value><string></string></value>
</member>
</struct></value>
</param>
</params>
</methodCall>
Successful response:
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><struct>
<member><name>0</name>
<value><struct>
<member><name>id</name>
<value><string>1</string></value>
</member>
<member><name>lid</name>
<value><string></string></value>
</member>
<member><name>tid</name>
<value><string>n</string></value>
</member>
<member><name>owner</name>
<value><string>500</string></value>
</member>
<member><name>access</name>
<value><string>private</string></value>
</member>
<member><name>cat_id</name>
<value><string>1</string></value>
</member>
<member><name>n_given</name>
<value><string>Alan</string></value>
</member>
</struct></value>
</member>
<member><name>1</name>
<value><struct>
<member><name>id</name>
<value><string>2</string></value>
</member>
<member><name>lid</name>
<value><string></string></value>
</member>
<member><name>tid</name>
<value><string>n</string></value>
</member>
<member><name>owner</name>
<value><string>500</string></value>
</member>
<member><name>access</name>
<value><string>private</string></value>
</member>
<member><name>cat_id</name>
<value><string>1</string></value>
</member>
<member><name>n_given</name>
<value><string>Andy</string></value>
</member>
</struct></value>
</member>
...
Unauthorized access attempt returns:
<methodResponse>
<params>
<param>
<value><string>UNAUTHORIZED</string></value>
</param>
</params>
</methodResponse>
3 More to come...
Documenting every single call will be difficult, but should
be done. In leiu of this, please see the class.bo{APPNAME}.inc.php
files in each application/inc directory in the phpgroupware
cvs. In this file will be a list_methods() function, which
returns the information to the server about input/output
structure for each call. If the file does not have this
function, then it is not yet workable via this interface.
As for the actual functions, they are also in this file.
Generally, they will all accept associative array input
and return same, but not always. This code is in flux, have
fun.