My SOAP experience was NONE before starting to work with Zimbra, that being said, there might be a better way to do what I'm about to post - but this worked for me in my organization for what they wanted (which was to be able to create an email account when an active directory account was created on a webform in our intranet). I expanded it to delete an account too. I set up the code to use 2 classes because if future functionality was needed, I should be able to just expand the classes and not have to rewrite a bunch of code.
public class SoapParameters
{
/// <summary>https://mydomain.com:7071/service/admin/soap/</summary>
internal string serviceAdminSoapUri { get; set; }
/// <summary>format:
abc@xyz.com (administrator account that can make changes)</summary>
internal string adminUsername { get; set; }
/// <summary>(administrator account that can make changes)</summary>
internal string adminPassword { get; set; }
internal string authToken { get; set; }
/// <summary>format:
abc@xyz.com (account to which to perform soapCommand on)</summary>
public string accountUsername { get; set; }
public string accountFirstName { get; set; }
public string accountLastName { get; set; }
public string accountDisplayName
{
get { return string.Format("{0} {1}", accountFirstName ,accountLastName); }
}
internal string accountId { get; set; }
public SoapParameters()
{
string impersonateDomain = System.Configuration.ConfigurationSettings.AppSett ings["Domain.Settings.ImpersonateDomain"];
string impersonateUsername = System.Configuration.ConfigurationSettings.AppSett ings["Domain.Settings.ImpersonateUsername"];
string impersonatePassword = System.Configuration.ConfigurationSettings.AppSett ings["Domain.Settings.ImpersonatePassword"];
string zimbraServiceAdminSoapUri = System.Configuration.ConfigurationSettings.AppSett ings["Domain.Settings.ZimbraServiceAdminSoapUri"];
adminUsername = string.Format("{0}@{1}", impersonateUsername, impersonateDomain);
adminPassword = impersonatePassword;
serviceAdminSoapUri = zimbraServiceAdminSoapUri;
}
//
http://zimbra.svn.sourceforge.net/vi...soap-admin.txt
public class AccountService
{
private enum SoapMessages
{
AuthenticationToken,
CreateAccount,
RemoveAccount,
Account
}
/// <summary>Get First and Last Name of an account based on email address</summary>
/// <param name="param">just include an email address</param>
public static SoapParameters Read(SoapParameters param)
{
GetAdministratorAuthenticationToken(param);
GetAccount(param);
return param;
}
public static void Create(SoapParameters param)
{
GetAdministratorAuthenticationToken(param);
CreateAccountRequest(param);
}
/// <summary>Remove an account based on email address</summary>
/// <param name="param">just include an email address</param>
public static void Delete(SoapParameters param)
{
GetAdministratorAuthenticationToken(param);
GetAccount(param);
RemoveAccountRequest(param);
}
private static void GetAdministratorAuthenticationToken(SoapParameters param)
{
XmlDocument doc = GetResponseDoc(param, SoapMessages.AuthenticationToken);
param.authToken = doc.GetElementsByTagName("authToken").Item(0).Inne rXml;
}
private static void CreateAccountRequest(SoapParameters param)
{
XmlDocument doc = GetResponseDoc(param, SoapMessages.CreateAccount);
try
{
string value = doc.GetElementsByTagName("CreateAccountResponse"). Item(0).ChildNodes[0].Attributes["id"].Value;
Guid guid = new Guid(value);
param.accountId = guid.ToString();
}
catch
{
throw new Exception("Account Did Not Appear To Be Created.");
}
}
public static void GetAccount(SoapParameters param)
{
XmlDocument doc = GetResponseDoc(param, SoapMessages.Account);
param.accountFirstName = null;
param.accountLastName = null;
param.accountId = null;
string tag = "GetAccountResponse";
string attr;
string value;
int i = 0;
int max = doc.GetElementsByTagName(tag).Item(0).ChildNodes[0].ChildNodes.Count;
for (int x = 0; x < doc.GetElementsByTagName(tag).Item(0).ChildNodes[0].Attributes.Count; x++)
{
attr = doc.GetElementsByTagName(tag).Item(0).ChildNodes[0].Attributes[x].Name.ToLower();
value = doc.GetElementsByTagName(tag).Item(0).ChildNodes[0].Attributes[x].InnerText;
switch (attr)
{
case "id":
try
{
Guid guid = new Guid(value);
param.accountId = guid.ToString();
}
catch { }
break;
}
}
while (i < max)
{
attr = doc.GetElementsByTagName("GetAccountResponse").Ite m(0).ChildNodes[0].ChildNodes[i].Attributes[0].Value.ToLower();
value = doc.GetElementsByTagName("GetAccountResponse").Ite m(0).ChildNodes[0].ChildNodes[i].InnerText;
switch (attr)
{
case "givenname":
param.accountFirstName = value;
break;
case "sn":
param.accountLastName = value;
break;
}
i = (param.accountFirstName == null || param.accountLastName == null) ? i + 1 : max;
}
}
private static void RemoveAccountRequest(SoapParameters param)
{
XmlDocument doc = GetResponseDoc(param, SoapMessages.RemoveAccount);
if (doc == null)
throw new Exception("Unsure if account was removed, please have administrator check.");
}
private static XmlDocument GetResponseDoc(SoapParameters param, SoapMessages message)
{
string soapMessage = SoapMessageBuilder(message, param);
XmlDocument requestDoc = new XmlDocument();
requestDoc.LoadXml(soapMessage);
HttpWebRequest request = HttpWebRequestBuilder(param.serviceAdminSoapUri);
Stream stm = request.GetRequestStream();
requestDoc.Save(stm);
stm.Close();
WebResponse resp = request.GetResponse();
stm = resp.GetResponseStream();
StreamReader r = new StreamReader(stm);
XmlDocument responseDoc = new XmlDocument();
responseDoc.LoadXml(r.ReadToEnd());
return responseDoc;
}
private static HttpWebRequest HttpWebRequestBuilder(string serviceAdminSoapUri)
{
HttpWebRequest retVal = (HttpWebRequest)WebRequest.Create(serviceAdminSoap Uri);
retVal.Headers.Add("SOAPAction", "\"\"");
retVal.ContentType = "text/xml;charset=\"utf-8\"";
retVal.Accept = "text/xml";
retVal.Method = "POST";
return retVal;
}
private static string SoapMessageBuilder(SoapMessages message, SoapParameters param)
{
string retVal = "";
switch (message)
{
case SoapMessages.AuthenticationToken:
retVal = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">" +
"<soap:Header>" +
"<context xmlns=\"urn:zimbra\"/>" +
"</soap:Header>" +
"<soap:Body>" +
"<AuthRequest xmlns=\"urn:zimbraAdmin\">" +
"<name>" + param.adminUsername + "</name>" +
"<password>" + param.adminPassword + "</password>" +
"</AuthRequest>" +
"</soap:Body>" +
"</soap:Envelope>";
break;
case SoapMessages.CreateAccount:
retVal = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">" +
"<soap:Header>" +
"<context xmlns=\"urn:zimbra\">" +
"<authToken>" + param.authToken + "</authToken>" +
"</context>" +
"</soap:Header>" +
"<soap:Body>" +
"<CreateAccountRequest xmlns=\"urn:zimbraAdmin\">" +
"<name>" + param.accountUsername +"</name>" +
"<password></password>" +
"<a n=\"givenName\">" + param.accountFirstName + "</a>" +
"<a n=\"sn\">" + param.accountLastName + "</a>" +
"<a n=\"displayName\">" + param.accountDisplayName + "</a>" +
"</CreateAccountRequest>" +
"</soap:Body>" +
"</soap:Envelope>";
break;
case SoapMessages.RemoveAccount:
retVal = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">" +
"<soap:Header>" +
"<context xmlns=\"urn:zimbra\">" +
"<authToken>" + param.authToken + "</authToken>" +
"</context>" +
"</soap:Header>" +
"<soap:Body>" +
"<DeleteAccountRequest xmlns=\"urn:zimbraAdmin\">" +
"<id>" + param.accountId + "</id>" +
"</DeleteAccountRequest>" +
"</soap:Body>" +
"</soap:Envelope>";
break;
case SoapMessages.Account:
retVal = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">" +
"<soap:Header>" +
"<context xmlns=\"urn:zimbra\">" +
"<authToken>" + param.authToken + "</authToken>" +
"</context>" +
"</soap:Header>" +
"<soap:Body>" +
"<GetAccountRequest xmlns=\"urn:zimbraAdmin\">" +
"<account by=\"name\">" + param.accountUsername + "</account>" +
"</GetAccountRequest>" +
"</soap:Body>" +
"</soap:Envelope>";
break;
}
return retVal;
}
}
... and finally, an example of use:
private static void CreateNewZimbraAccount(string username, string domainName, string firstName, string lastName)
{
SoapParameters myParam = new SoapParameters()
{
accountUsername = string.Format("{0}@{1}", username, domainName),
accountFirstName = firstName,
accountLastName = lastName,
};
Domain.Zimbra.AccountService.Create(myParam);
}