Skip to content

Commit acf2a83

Browse files
committed
Add EqualFold function on AttributeTypeAndValue.
Since v3 ldap we have case insensitive search in parallel to a case sensitive search: I would like to propose to add an EqualFold function in parallel to Equal function in dn.go on AttributeTypeAndValue. So we can not only search in case sensitive but also compare RDNs.
1 parent c9551dc commit acf2a83

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

dn.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,66 @@ func (r *RelativeDN) hasAllAttributes(attrs []*AttributeTypeAndValue) bool {
205205
func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bool {
206206
return strings.EqualFold(a.Type, other.Type) && a.Value == other.Value
207207
}
208+
209+
// Equal returns true if the DNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch).
210+
// Returns true if they have the same number of relative distinguished names
211+
// and corresponding relative distinguished names (by position) are the same.
212+
// Case of the attribute type and value is not significant
213+
func (d *DN) EqualFold(other *DN) bool {
214+
if len(d.RDNs) != len(other.RDNs) {
215+
return false
216+
}
217+
for i := range d.RDNs {
218+
if !d.RDNs[i].EqualFold(other.RDNs[i]) {
219+
return false
220+
}
221+
}
222+
return true
223+
}
224+
225+
// AncestorOfFold returns true if the other DN consists of at least one RDN followed by all the RDNs of the current DN.
226+
// Case of the attribute type and value is not significant
227+
func (d *DN) AncestorOfFold(other *DN) bool {
228+
if len(d.RDNs) >= len(other.RDNs) {
229+
return false
230+
}
231+
// Take the last `len(d.RDNs)` RDNs from the other DN to compare against
232+
otherRDNs := other.RDNs[len(other.RDNs)-len(d.RDNs):]
233+
for i := range d.RDNs {
234+
if !d.RDNs[i].EqualFold(otherRDNs[i]) {
235+
return false
236+
}
237+
}
238+
return true
239+
}
240+
241+
// Equal returns true if the RelativeDNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch).
242+
// Case of the attribute type is not significant
243+
func (r *RelativeDN) EqualFold(other *RelativeDN) bool {
244+
if len(r.Attributes) != len(other.Attributes) {
245+
return false
246+
}
247+
return r.hasAllAttributesFold(other.Attributes) && other.hasAllAttributesFold(r.Attributes)
248+
}
249+
250+
func (r *RelativeDN) hasAllAttributesFold(attrs []*AttributeTypeAndValue) bool {
251+
for _, attr := range attrs {
252+
found := false
253+
for _, myattr := range r.Attributes {
254+
if myattr.EqualFold(attr) {
255+
found = true
256+
break
257+
}
258+
}
259+
if !found {
260+
return false
261+
}
262+
}
263+
return true
264+
}
265+
266+
// EqualFold returns true if the AttributeTypeAndValue is equivalent to the specified AttributeTypeAndValue
267+
// Case of the attribute type and value is not significant
268+
func (a *AttributeTypeAndValue) EqualFold(other *AttributeTypeAndValue) bool {
269+
return strings.EqualFold(a.Type, other.Type) && strings.EqualFold(a.Value, other.Value)
270+
}

v3/dn.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,66 @@ func (r *RelativeDN) hasAllAttributes(attrs []*AttributeTypeAndValue) bool {
205205
func (a *AttributeTypeAndValue) Equal(other *AttributeTypeAndValue) bool {
206206
return strings.EqualFold(a.Type, other.Type) && a.Value == other.Value
207207
}
208+
209+
// Equal returns true if the DNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch).
210+
// Returns true if they have the same number of relative distinguished names
211+
// and corresponding relative distinguished names (by position) are the same.
212+
// Case of the attribute type and value is not significant
213+
func (d *DN) EqualFold(other *DN) bool {
214+
if len(d.RDNs) != len(other.RDNs) {
215+
return false
216+
}
217+
for i := range d.RDNs {
218+
if !d.RDNs[i].EqualFold(other.RDNs[i]) {
219+
return false
220+
}
221+
}
222+
return true
223+
}
224+
225+
// AncestorOfFold returns true if the other DN consists of at least one RDN followed by all the RDNs of the current DN.
226+
// Case of the attribute type and value is not significant
227+
func (d *DN) AncestorOfFold(other *DN) bool {
228+
if len(d.RDNs) >= len(other.RDNs) {
229+
return false
230+
}
231+
// Take the last `len(d.RDNs)` RDNs from the other DN to compare against
232+
otherRDNs := other.RDNs[len(other.RDNs)-len(d.RDNs):]
233+
for i := range d.RDNs {
234+
if !d.RDNs[i].EqualFold(otherRDNs[i]) {
235+
return false
236+
}
237+
}
238+
return true
239+
}
240+
241+
// Equal returns true if the RelativeDNs are equal as defined by rfc4517 4.2.15 (distinguishedNameMatch).
242+
// Case of the attribute type is not significant
243+
func (r *RelativeDN) EqualFold(other *RelativeDN) bool {
244+
if len(r.Attributes) != len(other.Attributes) {
245+
return false
246+
}
247+
return r.hasAllAttributesFold(other.Attributes) && other.hasAllAttributesFold(r.Attributes)
248+
}
249+
250+
func (r *RelativeDN) hasAllAttributesFold(attrs []*AttributeTypeAndValue) bool {
251+
for _, attr := range attrs {
252+
found := false
253+
for _, myattr := range r.Attributes {
254+
if myattr.EqualFold(attr) {
255+
found = true
256+
break
257+
}
258+
}
259+
if !found {
260+
return false
261+
}
262+
}
263+
return true
264+
}
265+
266+
// EqualFold returns true if the AttributeTypeAndValue is equivalent to the specified AttributeTypeAndValue
267+
// Case of the attribute type and value is not significant
268+
func (a *AttributeTypeAndValue) EqualFold(other *AttributeTypeAndValue) bool {
269+
return strings.EqualFold(a.Type, other.Type) && strings.EqualFold(a.Value, other.Value)
270+
}

0 commit comments

Comments
 (0)