зеркало из https://github.com/mozilla/pjs.git
Bug 356208 Create an nsAbLDAPDirectoryModify class, writeable ldap not yet enabled see bug 86405 for current status. patch originally by me, large updates by Jeremy Lain�� <jeremy.laine@m4x.org>, further small fixes by me. r=bienvenu,sr=mscott
This commit is contained in:
Родитель
64fd100a67
Коммит
dbd7c5bdf8
|
@ -81,6 +81,7 @@ XPIDLSRCS += \
|
|||
nsIAbLDAPReplicationQuery.idl \
|
||||
nsIAbLDAPReplicationData.idl \
|
||||
nsIAbLDAPDirectory.idl \
|
||||
nsIAbLDAPCard.idl \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Dan Mosedale <dan.mosedale@oracle.com>
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -66,7 +67,7 @@ interface nsIAbCard;
|
|||
* draft-joslin-config-schema-11.txt), we can simplify this and other
|
||||
* code and only allow a property to map to a single attribute.
|
||||
*/
|
||||
[scriptable, uuid(2ba46eae-9141-4d79-af90-3c7ecf2dc357)]
|
||||
[scriptable, uuid(bc543118-db5d-4616-b2d4-9a8667609a7c)]
|
||||
interface nsIAbLDAPAttributeMap : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -143,6 +144,17 @@ interface nsIAbLDAPAttributeMap : nsISupports
|
|||
* @exception NS_ERROR_FAILURE there are no attributes in this property map
|
||||
*/
|
||||
ACString getAllCardAttributes();
|
||||
|
||||
/**
|
||||
* Get all properties that may be used in an addressbook card via this
|
||||
* property map.
|
||||
*
|
||||
* @return an array of properties
|
||||
*
|
||||
* @exception NS_ERROR_FAILURE there are no attributes in this property map
|
||||
*/
|
||||
void getAllCardProperties(out unsigned long aCount,
|
||||
[retval, array, size_is(aCount)] out string aProps);
|
||||
|
||||
/**
|
||||
* Check that no LDAP attributes are listed in more than one property.
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mark Banner <bugzilla@standard8.plus.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIAbCard.idl"
|
||||
|
||||
interface nsIAbLDAPAttributeMap;
|
||||
interface nsILDAPModification;
|
||||
interface nsILDAPMessage;
|
||||
interface nsIArray;
|
||||
|
||||
[scriptable, uuid(2831b3b0-30ef-4070-8ad3-90ae04980e11)]
|
||||
interface nsIAbLDAPCard : nsISupports
|
||||
{
|
||||
/**
|
||||
* Returns the required information for an LDAP update message.
|
||||
*
|
||||
* @param aAttrMap The map between LDAP attributes and card properties
|
||||
* @param aClassCount The number of objectClass values
|
||||
* @param aClasses The objectClass values that the card needs to have
|
||||
* @param updateType This should be one of:
|
||||
* nsILDAPModification::MOD_ADD
|
||||
* nsILDAPModification::MOD_REPLACE
|
||||
*
|
||||
* @return Returns an array of modifications required to
|
||||
* add or replace the card in the ldap directory.
|
||||
*/
|
||||
nsIArray getLDAPMessageInfo(in nsIAbLDAPAttributeMap aAttrMap,
|
||||
in unsigned long aClassCount,
|
||||
[array, size_is(aClassCount)] in string aClasses,
|
||||
in long updateType);
|
||||
|
||||
/**
|
||||
* Builds a relative distinguished name (RDN) with the given set of
|
||||
* attributes.
|
||||
*
|
||||
* @param aAttrMap The map between LDAP attributes and card properties
|
||||
* @param aAttrCount The number of attributes to use for the RDN
|
||||
* @param aAttributes The name of the attributes to use for the RDN
|
||||
*
|
||||
*/
|
||||
ACString buildRdn(in nsIAbLDAPAttributeMap aAttrMap,
|
||||
in unsigned long aAttrCount,
|
||||
[array, size_is(aAttrCount)] in string aAttributes);
|
||||
|
||||
/**
|
||||
* Stores meta-properties from a raw LDAP search result.
|
||||
*
|
||||
* @param aMessage The LDAP search result message.
|
||||
*
|
||||
*/
|
||||
void setMetaProperties(in nsILDAPMessage aMessage);
|
||||
|
||||
attribute ACString dn;
|
||||
};
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Dan Mosedale <dan.mosedale@oracle.com>
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -115,5 +116,23 @@ interface nsIAbLDAPDirectory : nsISupports
|
|||
* A database that is set up for the replication file.
|
||||
*/
|
||||
readonly attribute nsIAddrDatabase replicationDatabase;
|
||||
|
||||
/**
|
||||
* The LDAP attributes used to build the Relative Distinguished Name
|
||||
* of new cards, in the form of a comma separated list.
|
||||
*
|
||||
* The default is to use the common name (cn) attribute.
|
||||
*/
|
||||
attribute ACString rdnAttributes;
|
||||
|
||||
/**
|
||||
* The LDAP objectClass values added to cards when they are created/added,
|
||||
* in the form of a comma separated list.
|
||||
*
|
||||
* The default is to use the following classes:
|
||||
* top,person,organizationalPerson,inetOrgPerson,mozillaAbPersonAlpha
|
||||
*/
|
||||
attribute ACString objectClasses;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ CPPSRCS += \
|
|||
nsAbLDAPCard.cpp \
|
||||
nsAbLDAPListenerBase.cpp \
|
||||
nsAbLDAPDirectoryQuery.cpp \
|
||||
nsAbLDAPDirectoryModify.cpp \
|
||||
nsAbBoolExprToLDAPFilter.cpp \
|
||||
nsAbLDAPAutoCompFormatter.cpp \
|
||||
nsAbLDAPReplicationService.cpp \
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Dan Mosedale <dan.mosedale@oracle.com>
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -130,6 +131,17 @@ nsAbLDAPAttributeMap.prototype = {
|
|||
|
||||
return attrs.join(",");
|
||||
},
|
||||
|
||||
getAllCardProperties: function getAllCardProperties(aCount) {
|
||||
|
||||
var props = [];
|
||||
for (var prop in this.mPropertyMap) {
|
||||
props.push(prop);
|
||||
}
|
||||
|
||||
aCount.value = props.length;
|
||||
return props;
|
||||
},
|
||||
|
||||
setFromPrefs: function setFromPrefs(aPrefBranchName) {
|
||||
var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -21,6 +21,8 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Created by: Paul Sandoz <paul.sandoz@sun.com>
|
||||
* Mark Banner <bugzilla@standard8.plus.com>
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -37,10 +39,15 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAbLDAPCard.h"
|
||||
|
||||
// XXX Although this has no real use at the moment, its planned to be
|
||||
// used for writeable ldap directories as part of bug 86405 so we don't
|
||||
// want to remove it just to add it back in later...
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsILDAPModification.h"
|
||||
#include "nsILDAPBERValue.h"
|
||||
#include "nsILDAPMessage.h"
|
||||
#include "nsIAbLDAPAttributeMap.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsAbBaseCID.h"
|
||||
#include "nsAbUtils.h"
|
||||
|
||||
nsAbLDAPCard::nsAbLDAPCard()
|
||||
{
|
||||
|
@ -50,5 +57,265 @@ nsAbLDAPCard::~nsAbLDAPCard()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsAbLDAPCard, nsAbCardProperty)
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsAbLDAPCard, nsAbCardProperty, nsIAbLDAPCard)
|
||||
|
||||
/* Retrieves the changes to the LDAP card and stores them in an LDAP
|
||||
* update message.
|
||||
*
|
||||
* Calling this method changes the LDAP card, it updates the
|
||||
* meta-properties (m_*) to reflect what the LDAP contents will be once
|
||||
* the update has been performed. This allows you to do multiple (successful)
|
||||
* consecutive edits on a card in a search result. If the meta-properties
|
||||
* were not updated, incorrect assuptions would be made about what object
|
||||
* classes to add, or what attributes to clear.
|
||||
*
|
||||
* XXX: We need to take care when integrating this code with the asynchronous
|
||||
* update dialogs, as the current code in nsAbLDAPDirectory has a problem
|
||||
* when an update fails: the modified card still gets stored and shown to
|
||||
* the user instead of being discarded. There is one especially tricky case:
|
||||
* when you do an update on a card which changes its DN, you have two
|
||||
* operations (rename, then update the other attributes). If the rename
|
||||
* operation succeeds and not the update of the attributes, you are
|
||||
* "somewhere in between" the original card and the updated card.
|
||||
*/
|
||||
NS_IMETHODIMP nsAbLDAPCard::GetLDAPMessageInfo(
|
||||
nsIAbLDAPAttributeMap *aAttributeMap,
|
||||
const PRUint32 aClassCount,
|
||||
const char **aClasses,
|
||||
PRInt32 aType,
|
||||
nsIArray **aLDAPAddMessageInfo)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAttributeMap);
|
||||
NS_ENSURE_ARG_POINTER(aClasses);
|
||||
NS_ENSURE_ARG_POINTER(aLDAPAddMessageInfo);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMutableArray> modArray =
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Add any missing object classes. We never remove any object
|
||||
// classes: if an entry has additional object classes, it's probably
|
||||
// for a good reason.
|
||||
nsCAutoString oclass;
|
||||
for (PRUint32 i = 0; i < aClassCount; ++i)
|
||||
{
|
||||
oclass.Assign(nsDependentCString(aClasses[i]));
|
||||
ToLowerCase(oclass);
|
||||
|
||||
if (m_objectClass.IndexOf(oclass) == -1)
|
||||
{
|
||||
m_objectClass.AppendCString(oclass);
|
||||
printf("LDAP : adding objectClass %s\n", oclass.get());
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILDAPModification> mod =
|
||||
do_CreateInstance("@mozilla.org/network/ldap-modification;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMutableArray> values =
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRInt32 i = 0; i < m_objectClass.Count(); ++i)
|
||||
{
|
||||
nsCOMPtr<nsILDAPBERValue> value =
|
||||
do_CreateInstance("@mozilla.org/network/ldap-ber-value;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = value->SetFromUTF8(*m_objectClass.CStringAt(i));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = values->AppendElement(value, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = mod->SetUpModification(aType, NS_LITERAL_CSTRING("objectClass"), values);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
modArray->AppendElement(mod, PR_FALSE);
|
||||
|
||||
// Add card properties
|
||||
CharPtrArrayGuard props;
|
||||
rv = aAttributeMap->GetAllCardProperties(props.GetSizeAddr(),
|
||||
props.GetArrayAddr());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString attr;
|
||||
nsString propvalue;
|
||||
for (PRUint32 i = 0; i < props.GetSize(); ++i)
|
||||
{
|
||||
// Skip some attributes that don't map to LDAP.
|
||||
//
|
||||
// BirthYear : by default this is mapped to 'birthyear',
|
||||
// which is not part of mozillaAbPersonAlpha
|
||||
//
|
||||
// LastModifiedDate : by default this is mapped to 'modifytimestamp',
|
||||
// which cannot be modified
|
||||
//
|
||||
// PreferMailFormat : by default this is mapped to 'mozillaUseHtmlMail',
|
||||
// which is a boolean, not plaintext/html/unknown
|
||||
if (!strcmp(props[i], "BirthYear") ||
|
||||
!strcmp(props[i], "LastModifiedDate") ||
|
||||
!strcmp(props[i], "PreferMailFormat"))
|
||||
continue;
|
||||
|
||||
rv = aAttributeMap->GetFirstAttribute(nsDependentCString(props[i]),
|
||||
attr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ToLowerCase(attr);
|
||||
|
||||
// If the property is not mapped to an attribute, skip it.
|
||||
if (attr.IsEmpty())
|
||||
continue;
|
||||
|
||||
rv = GetCardValue(props[i], propvalue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILDAPModification> mod =
|
||||
do_CreateInstance("@mozilla.org/network/ldap-modification;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!propvalue.IsEmpty())
|
||||
{
|
||||
// If the new value is not empty, add/update it
|
||||
nsCOMPtr<nsILDAPBERValue> value =
|
||||
do_CreateInstance("@mozilla.org/network/ldap-ber-value;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = value->SetFromUTF8(NS_ConvertUTF16toUTF8(propvalue));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mod->SetUpModificationOneValue(aType, attr, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
printf("LDAP : setting attribute %s (%s) to '%s'\n", attr.get(),
|
||||
props[i], NS_ConvertUTF16toUTF8(propvalue).get());
|
||||
modArray->AppendElement(mod, PR_FALSE);
|
||||
if (m_attributes.IndexOf(attr) != -1)
|
||||
m_attributes.AppendCString(attr);
|
||||
|
||||
}
|
||||
else if ((aType == nsILDAPModification::MOD_REPLACE) &&
|
||||
(m_attributes.IndexOf(attr) != -1))
|
||||
{
|
||||
// If the new value is empty, we are performing an update
|
||||
// and the attribute was previously set, clear it
|
||||
nsCOMPtr<nsIMutableArray> novalues =
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mod->SetUpModification(aType, attr, novalues);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
printf("LDAP : removing attribute %s (%s)\n", attr.get(), props[i]);
|
||||
modArray->AppendElement(mod, PR_FALSE);
|
||||
m_attributes.RemoveCString(attr);
|
||||
}
|
||||
}
|
||||
|
||||
NS_ADDREF(*aLDAPAddMessageInfo = modArray);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPCard::BuildRdn(nsIAbLDAPAttributeMap *aAttributeMap,
|
||||
const PRUint32 aAttrCount,
|
||||
const char **aAttributes,
|
||||
nsACString &aRdn)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAttributeMap);
|
||||
NS_ENSURE_ARG_POINTER(aAttributes);
|
||||
|
||||
nsresult rv;
|
||||
nsCAutoString attr;
|
||||
nsCAutoString prop;
|
||||
nsString propvalue;
|
||||
|
||||
aRdn.Truncate();
|
||||
for (PRUint32 i = 0; i < aAttrCount; ++i)
|
||||
{
|
||||
attr.Assign(nsDependentCString(aAttributes[i]));
|
||||
|
||||
// Lookup the property corresponding to the attribute
|
||||
rv = aAttributeMap->GetProperty(attr, prop);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get the property value
|
||||
rv = GetCardValue(prop.get(), propvalue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXX The case where an attribute needed to build the Relative
|
||||
// Distinguished Name is not set needs to be handled by the caller,
|
||||
// so as to let the user know what is missing.
|
||||
if (propvalue.IsEmpty())
|
||||
{
|
||||
NS_ERROR("nsAbLDAPCard::BuildRdn: a required attribute is not set");
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
aRdn.Append(attr);
|
||||
aRdn.AppendLiteral("=");
|
||||
aRdn.Append(NS_ConvertUTF16toUTF8(propvalue));
|
||||
if (i < aAttrCount - 1)
|
||||
aRdn.AppendLiteral("+");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPCard::GetDn(nsACString &aDN)
|
||||
{
|
||||
aDN = m_dn;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPCard::SetDn(const nsACString &aDN)
|
||||
{
|
||||
m_dn = aDN;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPCard::SetMetaProperties(nsILDAPMessage *aMessage)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMessage);
|
||||
|
||||
// Get DN
|
||||
nsCAutoString dn;
|
||||
nsresult rv = aMessage->GetDn(dn);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
m_dn = dn;
|
||||
|
||||
// Get the list of set attributes
|
||||
CharPtrArrayGuard attrs;
|
||||
rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString attr;
|
||||
m_attributes.Clear();
|
||||
for (PRUint32 i = 0; i < attrs.GetSize(); ++i)
|
||||
{
|
||||
attr.Assign(nsDependentCString(attrs[i]));
|
||||
ToLowerCase(attr);
|
||||
m_attributes.AppendCString(attr);
|
||||
}
|
||||
|
||||
// Get the objectClass values
|
||||
PRUnicharPtrArrayGuard vals;
|
||||
rv = aMessage->GetValues("objectClass", vals.GetSizeAddr(),
|
||||
vals.GetArrayAddr());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString oclass;
|
||||
m_objectClass.Clear();
|
||||
for (PRUint32 i = 0; i < vals.GetSize(); ++i)
|
||||
{
|
||||
oclass.Assign(NS_LossyConvertUTF16toASCII(nsDependentString(vals[i])));
|
||||
ToLowerCase(oclass);
|
||||
m_objectClass.AppendCString(oclass);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -21,6 +21,8 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Created by: Paul Sandoz <paul.sandoz@sun.com>
|
||||
* Mark Banner <bugzilla@standard8.plus.com>
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -40,15 +42,25 @@
|
|||
#define nsAbLDAPCard_h__
|
||||
|
||||
#include "nsAbCardProperty.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIAbLDAPCard.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
class nsAbLDAPCard : public nsAbCardProperty
|
||||
class nsIMutableArray;
|
||||
|
||||
class nsAbLDAPCard : public nsAbCardProperty,
|
||||
public nsIAbLDAPCard
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIABLDAPCARD
|
||||
|
||||
nsAbLDAPCard();
|
||||
virtual ~nsAbLDAPCard();
|
||||
nsAbLDAPCard();
|
||||
virtual ~nsAbLDAPCard();
|
||||
|
||||
protected:
|
||||
nsCString m_dn;
|
||||
nsCStringArray m_attributes;
|
||||
nsCStringArray m_objectClass;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
* Seth Spitzer <sspitzer@netscape.com>
|
||||
* Dan Mosedale <dmose@netscape.com>
|
||||
* Paul Sandoz <paul.sandoz@sun.com>
|
||||
* Mark Banner <mark@standard8.demon.co.uk>
|
||||
* Mark Banner <bugzilla@standard8.plus.com>
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -60,6 +61,10 @@
|
|||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsILDAPModification.h"
|
||||
#include "nsILDAPService.h"
|
||||
#include "nsIAbLDAPCard.h"
|
||||
#include "nsAbUtils.h"
|
||||
|
||||
#define kDefaultMaxHits 100
|
||||
|
||||
|
@ -128,9 +133,33 @@ NS_IMETHODIMP nsAbLDAPDirectory::GetURI(nsACString &aURI)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#define MOZ_EXPERIMENTAL_WRITEABLE_LDAP 1
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::GetOperations(PRInt32 *aOperations)
|
||||
{
|
||||
*aOperations = nsIAbDirectory::opSearch;
|
||||
|
||||
#ifdef MOZ_EXPERIMENTAL_WRITEABLE_LDAP
|
||||
PRBool readOnly;
|
||||
nsresult rv = GetBoolValue("readonly", PR_FALSE, &readOnly);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (readOnly)
|
||||
return NS_OK;
|
||||
|
||||
// when online, we'll allow writing as well
|
||||
PRBool offline;
|
||||
nsCOMPtr <nsIIOService> ioService =
|
||||
do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = ioService->GetOffline(&offline);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (!offline)
|
||||
*aOperations |= nsIAbDirectory::opWrite;
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -460,29 +489,25 @@ NS_IMETHODIMP nsAbLDAPDirectory::GetSearchDuringLocalAutocomplete(PRBool *aSearc
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbLDAPDirectory::GetSearchClientControls(nsIMutableArray **aControls)
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::GetSearchClientControls(nsIMutableArray **aControls)
|
||||
{
|
||||
NS_IF_ADDREF(*aControls = mSearchClientControls);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbLDAPDirectory::SetSearchClientControls(nsIMutableArray *aControls)
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::SetSearchClientControls(nsIMutableArray *aControls)
|
||||
{
|
||||
mSearchClientControls = aControls;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbLDAPDirectory::GetSearchServerControls(nsIMutableArray **aControls)
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::GetSearchServerControls(nsIMutableArray **aControls)
|
||||
{
|
||||
NS_IF_ADDREF(*aControls = mSearchServerControls);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAbLDAPDirectory::SetSearchServerControls(nsIMutableArray *aControls)
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::SetSearchServerControls(nsIMutableArray *aControls)
|
||||
{
|
||||
mSearchServerControls = aControls;
|
||||
return NS_OK;
|
||||
|
@ -565,6 +590,8 @@ NS_IMETHODIMP nsAbLDAPDirectory::SetDataVersion(const nsACString &aDataVersion)
|
|||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::GetAttributeMap(nsIAbLDAPAttributeMap **aAttributeMap)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAttributeMap);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIAbLDAPAttributeMapService> mapSvc =
|
||||
do_GetService("@mozilla.org/addressbook/ldap-attribute-map-service;1", &rv);
|
||||
|
@ -616,3 +643,247 @@ NS_IMETHODIMP nsAbLDAPDirectory::GetReplicationDatabase(nsIAddrDatabase **aResul
|
|||
return addrDBFactory->Open(databaseFile, PR_FALSE /* no create */, PR_TRUE,
|
||||
aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::AddCard(nsIAbCard *aUpdatedCard,
|
||||
nsIAbCard **aAddedCard)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aUpdatedCard);
|
||||
NS_ENSURE_ARG_POINTER(aAddedCard);
|
||||
|
||||
nsCOMPtr<nsIAbLDAPAttributeMap> attrMap;
|
||||
nsresult rv = GetAttributeMap(getter_AddRefs(attrMap));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create a new LDAP card
|
||||
nsCOMPtr<nsIAbLDAPCard> card =
|
||||
do_CreateInstance(NS_ABLDAPCARD_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = Initiate();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Copy over the card data
|
||||
nsCOMPtr<nsIAbCard> copyToCard = do_QueryInterface(card, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = copyToCard->Copy(aUpdatedCard);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Retrieve preferences
|
||||
nsCAutoString prefString;
|
||||
rv = GetRdnAttributes(prefString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
CharPtrArrayGuard rdnAttrs;
|
||||
rv = SplitStringList(prefString.get(), rdnAttrs.GetSizeAddr(),
|
||||
rdnAttrs.GetArrayAddr());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = GetObjectClasses(prefString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
CharPtrArrayGuard objClass;
|
||||
rv = SplitStringList(prefString.get(), objClass.GetSizeAddr(),
|
||||
objClass.GetArrayAddr());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Process updates
|
||||
nsCOMPtr<nsIArray> modArray;
|
||||
rv = card->GetLDAPMessageInfo(attrMap, objClass.GetSize(), objClass.GetArray(),
|
||||
nsILDAPModification::MOD_ADD, getter_AddRefs(modArray));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// For new cards, the base DN is the search base DN
|
||||
nsCOMPtr<nsILDAPURL> currentUrl;
|
||||
rv = GetLDAPURL(getter_AddRefs(currentUrl));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString baseDN;
|
||||
rv = currentUrl->GetDn(baseDN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Calculate DN
|
||||
nsCAutoString cardDN;
|
||||
rv = card->BuildRdn(attrMap, rdnAttrs.GetSize(), rdnAttrs.GetArray(),
|
||||
cardDN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
cardDN.AppendLiteral(",");
|
||||
cardDN.Append(baseDN);
|
||||
|
||||
rv = card->SetDn(cardDN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Launch query
|
||||
rv = DoModify(this, nsILDAPModification::MOD_ADD, cardDN, modArray,
|
||||
EmptyCString(), EmptyCString());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*aAddedCard = copyToCard);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::DeleteCards(nsISupportsArray *aCards)
|
||||
{
|
||||
PRUint32 cardCount;
|
||||
PRUint32 i;
|
||||
nsCAutoString cardDN;
|
||||
|
||||
nsresult rv = aCards->Count(&cardCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (i = 0; i < cardCount; ++i)
|
||||
{
|
||||
nsCOMPtr<nsIAbLDAPCard> card(do_QueryElementAt(aCards, i, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_WARNING("Wrong type of card passed to nsAbLDAPDirectory::DeleteCards");
|
||||
break;
|
||||
}
|
||||
|
||||
// Set up the search ldap url - this is mURL
|
||||
rv = Initiate();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = card->GetDn(cardDN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Launch query
|
||||
rv = DoModify(this, nsILDAPModification::MOD_DELETE, cardDN, nsnull,
|
||||
EmptyCString(), EmptyCString());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::ModifyCard(nsIAbCard *aUpdatedCard)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aUpdatedCard);
|
||||
|
||||
nsCOMPtr<nsIAbLDAPAttributeMap> attrMap;
|
||||
nsresult rv = GetAttributeMap(getter_AddRefs(attrMap));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get the LDAP card
|
||||
nsCOMPtr<nsIAbLDAPCard> card = do_QueryInterface(aUpdatedCard, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = Initiate();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Retrieve preferences
|
||||
nsCAutoString prefString;
|
||||
rv = GetObjectClasses(prefString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
CharPtrArrayGuard objClass;
|
||||
rv = SplitStringList(prefString.get(), objClass.GetSizeAddr(),
|
||||
objClass.GetArrayAddr());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Process updates
|
||||
nsCOMPtr<nsIArray> modArray;
|
||||
rv = card->GetLDAPMessageInfo(attrMap, objClass.GetSize(), objClass.GetArray(),
|
||||
nsILDAPModification::MOD_REPLACE, getter_AddRefs(modArray));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get current DN
|
||||
nsCAutoString oldDN;
|
||||
rv = card->GetDn(oldDN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILDAPService> ldapSvc = do_GetService(
|
||||
"@mozilla.org/network/ldap-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Retrieve base DN and RDN attributes
|
||||
nsCAutoString baseDN;
|
||||
nsCAutoString oldRDN;
|
||||
CharPtrArrayGuard rdnAttrs;
|
||||
rv = ldapSvc->ParseDn(oldDN.get(), oldRDN, baseDN,
|
||||
rdnAttrs.GetSizeAddr(), rdnAttrs.GetArrayAddr());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Calculate new RDN and check whether it has changed
|
||||
nsCAutoString newRDN;
|
||||
rv = card->BuildRdn(attrMap, rdnAttrs.GetSize(), rdnAttrs.GetArray(),
|
||||
newRDN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (newRDN.Equals(oldRDN))
|
||||
{
|
||||
// Launch query
|
||||
rv = DoModify(this, nsILDAPModification::MOD_REPLACE, oldDN, modArray,
|
||||
EmptyCString(), EmptyCString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build and store the new DN
|
||||
nsCAutoString newDN(newRDN);
|
||||
newDN.AppendLiteral(",");
|
||||
newDN.Append(baseDN);
|
||||
|
||||
rv = card->SetDn(newDN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Launch query
|
||||
rv = DoModify(this, nsILDAPModification::MOD_REPLACE, oldDN, modArray,
|
||||
newRDN, baseDN);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::GetRdnAttributes(nsACString &aRdnAttributes)
|
||||
{
|
||||
return GetStringValue("rdnAttributes", NS_LITERAL_CSTRING("cn"),
|
||||
aRdnAttributes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::SetRdnAttributes(const nsACString &aRdnAttributes)
|
||||
{
|
||||
return SetStringValue("rdnAttributes", aRdnAttributes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::GetObjectClasses(nsACString &aObjectClasses)
|
||||
{
|
||||
return GetStringValue("objectClasses", NS_LITERAL_CSTRING(
|
||||
"top,person,organizationalPerson,inetOrgPerson,mozillaAbPersonAlpha"),
|
||||
aObjectClasses);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbLDAPDirectory::SetObjectClasses(const nsACString &aObjectClasses)
|
||||
{
|
||||
return SetStringValue("objectClasses", aObjectClasses);
|
||||
}
|
||||
|
||||
nsresult nsAbLDAPDirectory::SplitStringList(
|
||||
const char *aString,
|
||||
PRUint32 *aCount,
|
||||
char ***aValues)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aString);
|
||||
NS_ENSURE_ARG_POINTER(aCount);
|
||||
NS_ENSURE_ARG_POINTER(aValues);
|
||||
|
||||
nsCStringArray strarr;
|
||||
strarr.ParseString(aString, ",");
|
||||
|
||||
char **cArray = nsnull;
|
||||
if (!(cArray = static_cast<char **>(nsMemory::Alloc(
|
||||
strarr.Count() * sizeof(char *)))))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
for (PRInt32 i = 0; i < strarr.Count(); ++i)
|
||||
{
|
||||
if (!(cArray[i] = ToNewCString(*strarr.CStringAt(i))))
|
||||
{
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(index, cArray);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
*aCount = strarr.Count();
|
||||
*aValues = cArray;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Seth Spitzer <sspitzer@netscape.com>
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -41,6 +42,7 @@
|
|||
|
||||
#include "nsAbDirectoryRDFResource.h"
|
||||
#include "nsAbDirProperty.h"
|
||||
#include "nsAbLDAPDirectoryModify.h"
|
||||
#include "nsIAbDirectoryQuery.h"
|
||||
#include "nsIAbDirectorySearch.h"
|
||||
#include "nsIAbDirSearchListener.h"
|
||||
|
@ -51,6 +53,7 @@
|
|||
class nsAbLDAPDirectory :
|
||||
public nsAbDirectoryRDFResource, // nsIRDFResource
|
||||
public nsAbDirProperty, // nsIAbDirectory
|
||||
public nsAbLDAPDirectoryModify,
|
||||
public nsIAbDirectorySearch,
|
||||
public nsIAbLDAPDirectory,
|
||||
public nsIAbDirSearchListener
|
||||
|
@ -73,6 +76,9 @@ public:
|
|||
NS_IMETHOD GetIsRemote(PRBool *aIsRemote);
|
||||
NS_IMETHOD GetIsSecure(PRBool *aIsRemote);
|
||||
NS_IMETHOD GetSearchDuringLocalAutocomplete(PRBool *aSearchDuringLocalAutocomplete);
|
||||
NS_IMETHOD AddCard(nsIAbCard *aChildCard, nsIAbCard **aAddedCard);
|
||||
NS_IMETHOD ModifyCard(nsIAbCard *aModifiedCard);
|
||||
NS_IMETHOD DeleteCards(nsISupportsArray *aCards);
|
||||
|
||||
// nsIAbDirectorySearch methods
|
||||
NS_DECL_NSIABDIRECTORYSEARCH
|
||||
|
@ -82,6 +88,10 @@ public:
|
|||
protected:
|
||||
nsresult Initiate();
|
||||
|
||||
nsresult SplitStringList(const char *aString,
|
||||
PRUint32 *aCount,
|
||||
char ***aValues);
|
||||
|
||||
PRPackedBool mPerformingQuery;
|
||||
PRInt32 mContext;
|
||||
PRInt32 mMaxHits;
|
||||
|
|
|
@ -0,0 +1,408 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mark Banner <bugzilla@standard8.plus.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAbLDAPDirectoryModify.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsILDAPMessage.h"
|
||||
#include "nsILDAPConnection.h"
|
||||
#include "nsILDAPErrors.h"
|
||||
#include "nsILDAPModification.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
#include "nsIAbLDAPDirectory.h"
|
||||
#include "nsIMutableArray.h"
|
||||
|
||||
class nsAbModifyLDAPMessageListener : public nsAbLDAPListenerBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsAbModifyLDAPMessageListener(const PRInt32 type,
|
||||
const nsACString &cardDN,
|
||||
nsIArray* modArray,
|
||||
const nsACString &newRDN,
|
||||
const nsACString &newBaseDN,
|
||||
nsILDAPURL* directoryUrl,
|
||||
nsILDAPConnection* connection,
|
||||
nsIMutableArray* serverSearchControls,
|
||||
nsIMutableArray* clientSearchControls,
|
||||
const nsACString &login,
|
||||
const PRInt32 timeOut = 0);
|
||||
virtual ~nsAbModifyLDAPMessageListener();
|
||||
|
||||
// nsILDAPMessageListener
|
||||
NS_IMETHOD OnLDAPMessage(nsILDAPMessage *aMessage);
|
||||
|
||||
protected:
|
||||
nsresult Cancel();
|
||||
virtual void InitFailed(PRBool aCancelled = PR_FALSE);
|
||||
virtual nsresult DoTask();
|
||||
nsresult DoMainTask();
|
||||
nsresult OnLDAPMessageModifyResult(nsILDAPMessage *aMessage);
|
||||
nsresult OnLDAPMessageRenameResult(nsILDAPMessage *aMessage);
|
||||
|
||||
PRInt32 mType;
|
||||
nsCString mCardDN;
|
||||
nsCOMPtr<nsIArray> mModification;
|
||||
nsCString mNewRDN;
|
||||
nsCString mNewBaseDN;
|
||||
|
||||
PRBool mFinished;
|
||||
PRBool mCanceled;
|
||||
PRBool mFlagRename;
|
||||
|
||||
nsCOMPtr<nsILDAPOperation> mModifyOperation;
|
||||
nsCOMPtr<nsIMutableArray> mServerSearchControls;
|
||||
nsCOMPtr<nsIMutableArray> mClientSearchControls;
|
||||
};
|
||||
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsAbModifyLDAPMessageListener, nsILDAPMessageListener)
|
||||
|
||||
nsAbModifyLDAPMessageListener::nsAbModifyLDAPMessageListener(
|
||||
const PRInt32 type,
|
||||
const nsACString &cardDN,
|
||||
nsIArray* modArray,
|
||||
const nsACString &newRDN,
|
||||
const nsACString &newBaseDN,
|
||||
nsILDAPURL* directoryUrl,
|
||||
nsILDAPConnection* connection,
|
||||
nsIMutableArray* serverSearchControls,
|
||||
nsIMutableArray* clientSearchControls,
|
||||
const nsACString &login,
|
||||
const PRInt32 timeOut) :
|
||||
nsAbLDAPListenerBase(directoryUrl, connection, login, timeOut),
|
||||
mType(type),
|
||||
mCardDN(cardDN),
|
||||
mModification(modArray),
|
||||
mNewRDN(newRDN),
|
||||
mNewBaseDN(newBaseDN),
|
||||
mFinished(PR_FALSE),
|
||||
mCanceled(PR_FALSE),
|
||||
mFlagRename(PR_FALSE),
|
||||
mServerSearchControls(serverSearchControls),
|
||||
mClientSearchControls(clientSearchControls)
|
||||
{
|
||||
if (mType == nsILDAPModification::MOD_REPLACE &&
|
||||
!mNewRDN.IsEmpty() && !mNewBaseDN.IsEmpty())
|
||||
mFlagRename = PR_TRUE;
|
||||
}
|
||||
|
||||
nsAbModifyLDAPMessageListener::~nsAbModifyLDAPMessageListener ()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult nsAbModifyLDAPMessageListener::Cancel ()
|
||||
{
|
||||
nsresult rv = Initiate();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
if (mFinished || mCanceled)
|
||||
return NS_OK;
|
||||
|
||||
mCanceled = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbModifyLDAPMessageListener::OnLDAPMessage(nsILDAPMessage *aMessage)
|
||||
{
|
||||
nsresult rv = Initiate();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 messageType;
|
||||
rv = aMessage->GetType(&messageType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool cancelOperation = PR_FALSE;
|
||||
|
||||
// Enter lock
|
||||
{
|
||||
nsAutoLock lock (mLock);
|
||||
|
||||
if (mFinished)
|
||||
return NS_OK;
|
||||
|
||||
// for these messages, no matter the outcome, we're done
|
||||
if ((messageType == nsILDAPMessage::RES_ADD) ||
|
||||
(messageType == nsILDAPMessage::RES_DELETE) ||
|
||||
(messageType == nsILDAPMessage::RES_MODIFY))
|
||||
mFinished = PR_TRUE;
|
||||
else if (mCanceled)
|
||||
{
|
||||
mFinished = PR_TRUE;
|
||||
cancelOperation = PR_TRUE;
|
||||
}
|
||||
}
|
||||
// Leave lock
|
||||
|
||||
// nsCOMPtr<nsIAbDirectoryQueryResult> queryResult;
|
||||
if (!cancelOperation)
|
||||
{
|
||||
switch (messageType)
|
||||
{
|
||||
case nsILDAPMessage::RES_BIND:
|
||||
rv = OnLDAPMessageBind(aMessage);
|
||||
if (NS_FAILED(rv))
|
||||
// We know the bind failed and hence the message has an error, so we
|
||||
// can just call ModifyResult with the message and that'll sort it out
|
||||
// for us.
|
||||
rv = OnLDAPMessageModifyResult(aMessage);
|
||||
break;
|
||||
case nsILDAPMessage::RES_ADD:
|
||||
case nsILDAPMessage::RES_MODIFY:
|
||||
case nsILDAPMessage::RES_DELETE:
|
||||
rv = OnLDAPMessageModifyResult(aMessage);
|
||||
break;
|
||||
case nsILDAPMessage::RES_MODDN:
|
||||
mFlagRename = PR_FALSE;
|
||||
rv = OnLDAPMessageRenameResult(aMessage);
|
||||
if (NS_FAILED(rv))
|
||||
// Rename failed, so we stop here
|
||||
mFinished = PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mModifyOperation)
|
||||
rv = mModifyOperation->AbandonExt();
|
||||
|
||||
// reset because we might re-use this listener...except don't do this
|
||||
// until the search is done, so we'll ignore results from a previous
|
||||
// search.
|
||||
mCanceled = mFinished = PR_FALSE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void nsAbModifyLDAPMessageListener::InitFailed(PRBool aCancelled)
|
||||
{
|
||||
// XXX Just cancel the operation for now
|
||||
// we'll need to review this when we've got the proper listeners in place.
|
||||
Cancel();
|
||||
}
|
||||
|
||||
nsresult nsAbModifyLDAPMessageListener::DoTask()
|
||||
{
|
||||
nsresult rv;
|
||||
mCanceled = mFinished = PR_FALSE;
|
||||
|
||||
mModifyOperation = do_CreateInstance(NS_LDAPOPERATION_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILDAPMessageListener> proxyListener;
|
||||
rv = NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD,
|
||||
NS_GET_IID(nsILDAPMessageListener),
|
||||
this, NS_PROXY_SYNC | NS_PROXY_ALWAYS,
|
||||
getter_AddRefs(proxyListener));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mModifyOperation->Init (mConnection, proxyListener, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXX do we need the search controls?
|
||||
rv = mModifyOperation->SetServerControls(mServerSearchControls);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mModifyOperation->SetClientControls(mClientSearchControls);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mFlagRename)
|
||||
return mModifyOperation->Rename(mCardDN, mNewRDN, mNewBaseDN, PR_TRUE);
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case nsILDAPModification::MOD_ADD:
|
||||
return mModifyOperation->AddExt(mCardDN, mModification);
|
||||
case nsILDAPModification::MOD_DELETE:
|
||||
return mModifyOperation->DeleteExt(mCardDN);
|
||||
case nsILDAPModification::MOD_REPLACE:
|
||||
return mModifyOperation->ModifyExt(mCardDN, mModification);
|
||||
default:
|
||||
NS_ERROR("Bad LDAP modification requested");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsAbModifyLDAPMessageListener::OnLDAPMessageModifyResult(nsILDAPMessage *aMessage)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ENSURE_ARG_POINTER(aMessage);
|
||||
|
||||
PRInt32 errCode;
|
||||
rv = aMessage->GetErrorCode(&errCode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (errCode != nsILDAPErrors::SUCCESS)
|
||||
{
|
||||
nsCAutoString errMessage;
|
||||
rv = aMessage->GetErrorMessage(errMessage);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
printf("LDAP modification failed (code: %i, message: %s)\n",
|
||||
errCode, errMessage.get());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
printf("LDAP modification succeeded\n");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAbModifyLDAPMessageListener::OnLDAPMessageRenameResult(nsILDAPMessage *aMessage)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ENSURE_ARG_POINTER(aMessage);
|
||||
|
||||
PRInt32 errCode;
|
||||
rv = aMessage->GetErrorCode(&errCode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (errCode != nsILDAPErrors::SUCCESS)
|
||||
{
|
||||
nsCAutoString errMessage;
|
||||
rv = aMessage->GetErrorMessage(errMessage);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
printf("LDAP rename failed (code: %i, message: %s)\n",
|
||||
errCode, errMessage.get());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Rename succeeded, now update the card DN and
|
||||
// process the main task
|
||||
mCardDN.Assign(mNewRDN);
|
||||
mCardDN.AppendLiteral(",");
|
||||
mCardDN.Append(mNewBaseDN);
|
||||
|
||||
printf("LDAP rename succeeded\n");
|
||||
return DoTask();
|
||||
}
|
||||
|
||||
nsAbLDAPDirectoryModify::nsAbLDAPDirectoryModify()
|
||||
{
|
||||
}
|
||||
|
||||
nsAbLDAPDirectoryModify::~nsAbLDAPDirectoryModify()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult nsAbLDAPDirectoryModify::DoModify(nsIAbLDAPDirectory *directory,
|
||||
const PRInt32 &updateType,
|
||||
const nsACString &cardDN,
|
||||
nsIArray* modArray,
|
||||
const nsACString &newRDN,
|
||||
const nsACString &newBaseDN)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(directory);
|
||||
// modArray may be null in the delete operation case.
|
||||
if (!modArray &&
|
||||
(updateType == nsILDAPModification::MOD_ADD ||
|
||||
updateType == nsILDAPModification::MOD_REPLACE))
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// it's an error if we don't have a dn
|
||||
if (cardDN.IsEmpty())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsILDAPURL> currentUrl;
|
||||
rv = directory->GetLDAPURL(getter_AddRefs(currentUrl));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get the ldap connection
|
||||
nsCOMPtr<nsILDAPConnection> ldapConnection =
|
||||
do_CreateInstance(NS_LDAPCONNECTION_CONTRACTID, &rv);
|
||||
|
||||
nsCOMPtr<nsIMutableArray> serverSearchControls;
|
||||
rv = directory->GetSearchServerControls(getter_AddRefs(serverSearchControls));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMutableArray> clientSearchControls;
|
||||
rv = directory->GetSearchClientControls(getter_AddRefs(clientSearchControls));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
/*
|
||||
// XXX we need to fix how this all works - specifically, see the first patch
|
||||
// on bug 124553 for how the query equivalent did this
|
||||
// too soon? Do we need a new listener?
|
||||
if (alreadyInitialized)
|
||||
{
|
||||
nsAbQueryLDAPMessageListener *msgListener =
|
||||
NS_STATIC_CAST(nsAbQueryLDAPMessageListener *,
|
||||
NS_STATIC_CAST(nsILDAPMessageListener *, mListener.get()));
|
||||
if (msgListener)
|
||||
{
|
||||
msgListener->mUrl = url;
|
||||
return msgListener->DoSearch();
|
||||
}
|
||||
}*/
|
||||
|
||||
nsCString login;
|
||||
rv = directory->GetAuthDn(login);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 protocolVersion;
|
||||
rv = directory->GetProtocolVersion(&protocolVersion);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Initiate LDAP message listener
|
||||
nsAbModifyLDAPMessageListener* _messageListener =
|
||||
new nsAbModifyLDAPMessageListener(updateType, cardDN, modArray,
|
||||
newRDN, newBaseDN,
|
||||
currentUrl,
|
||||
ldapConnection,
|
||||
serverSearchControls,
|
||||
clientSearchControls,
|
||||
login,
|
||||
0);
|
||||
if (_messageListener == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Now lets initialize the LDAP connection properly. We'll kick
|
||||
// off the bind operation in the callback function, |OnLDAPInit()|.
|
||||
return ldapConnection->Init(currentUrl, login,
|
||||
_messageListener, nsnull, protocolVersion);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mark Banner <bugzilla@standard8.plus.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsAbLDAPDirectoryModify_h__
|
||||
#define nsAbLDAPDirectoryModify_h__
|
||||
|
||||
#include "nsAbLDAPListenerBase.h"
|
||||
#include "nsIAbLDAPDirectory.h"
|
||||
#include "nsILDAPOperation.h"
|
||||
#include "nsIArray.h"
|
||||
|
||||
class nsILDAPURL;
|
||||
|
||||
class nsAbLDAPDirectoryModify
|
||||
{
|
||||
public:
|
||||
nsAbLDAPDirectoryModify();
|
||||
virtual ~nsAbLDAPDirectoryModify();
|
||||
|
||||
protected:
|
||||
nsresult DoModify(nsIAbLDAPDirectory *directory,
|
||||
const PRInt32 &aUpdateType,
|
||||
const nsACString &aCardDN,
|
||||
nsIArray* modArray,
|
||||
const nsACString &aNewRDN,
|
||||
const nsACString &aNewBaseDN);
|
||||
};
|
||||
|
||||
#endif // nsAbLDAPDirectoryModify_h__
|
|
@ -23,7 +23,8 @@
|
|||
* Seth Spitzer <sspitzer@netscape.com>
|
||||
* Dan Mosedale <dmose@netscape.com>
|
||||
* Paul Sandoz <paul.sandoz@sun.com>
|
||||
* Mark Banner <mark@standard8.demon.co.uk>
|
||||
* Mark Banner <bugzilla@standard8.plus.com>
|
||||
* Jeremy Laine <jeremy.laine@m4x.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -45,6 +46,7 @@
|
|||
#include "nsILDAPErrors.h"
|
||||
#include "nsILDAPOperation.h"
|
||||
#include "nsIAbLDAPAttributeMap.h"
|
||||
#include "nsIAbLDAPCard.h"
|
||||
#include "nsAbUtils.h"
|
||||
#include "nsAbBaseCID.h"
|
||||
#include "nsString.h"
|
||||
|
@ -305,6 +307,12 @@ nsresult nsAbQueryLDAPMessageListener::OnLDAPMessageSearchEntry(nsILDAPMessage *
|
|||
|
||||
rv = map->SetCardPropertiesFromLDAPMessage(aMessage, card);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIAbLDAPCard> ldapCard = do_QueryInterface(card, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ldapCard->SetMetaProperties(aMessage);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return mResultListener->OnQueryFoundCard(card);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче