Migrate filter extensions (#809)
* Replace presence filter * Replace equality filter * Remove TODO * Fix integration tests * Replace approximate filter * Replace extensible filter * Replace greater-than-equals filter * Replace less-than-equals filter * Replace remaining filters * Remove debug code * Remove transition code * Remove unnecessry isFilter * Remove unused code * Use LDAP filter string parsing from @ldapjs/filter * Move BER filter parsing to @ldapjs/filter * Fully replace internal filters module with @ldapjs/filter
This commit is contained in:
parent
5bab39f58e
commit
9de9c703ab
|
@ -23,7 +23,7 @@ const SearchPager = require('./search_pager')
|
|||
const Protocol = require('@ldapjs/protocol')
|
||||
const dn = require('../dn')
|
||||
const errors = require('../errors')
|
||||
const filters = require('../filters')
|
||||
const filters = require('@ldapjs/filter')
|
||||
const messages = require('../messages')
|
||||
const url = require('../url')
|
||||
const CorkedEmitter = require('../corked_emitter')
|
||||
|
@ -572,7 +572,7 @@ Client.prototype.search = function search (base,
|
|||
options.filter = filters.parseString(options.filter)
|
||||
} else if (!options.filter) {
|
||||
options.filter = new PresenceFilter({ attribute: 'objectclass' })
|
||||
} else if (!filters.isFilter(options.filter)) {
|
||||
} else if (Object.prototype.toString.call(options.filter) !== '[object FilterString]') {
|
||||
throw new TypeError('options.filter (Filter) required')
|
||||
}
|
||||
if (typeof (controls) === 'function') {
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function AndFilter (options) {
|
||||
parents.AndFilter.call(this, options)
|
||||
}
|
||||
util.inherits(AndFilter, parents.AndFilter)
|
||||
Filter.mixin(AndFilter)
|
||||
module.exports = AndFilter
|
||||
|
||||
AndFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
this.filters.forEach(function (f) {
|
||||
ber = f.toBer(ber)
|
||||
})
|
||||
|
||||
return ber
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function ApproximateFilter (options) {
|
||||
parents.ApproximateFilter.call(this, options)
|
||||
}
|
||||
util.inherits(ApproximateFilter, parents.ApproximateFilter)
|
||||
Filter.mixin(ApproximateFilter)
|
||||
module.exports = ApproximateFilter
|
||||
|
||||
ApproximateFilter.prototype.parse = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
this.attribute = ber.readString().toLowerCase()
|
||||
this.value = ber.readString()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
ApproximateFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
ber.writeString(this.attribute)
|
||||
ber.writeString(this.value)
|
||||
|
||||
return ber
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert-plus')
|
||||
const util = require('util')
|
||||
|
||||
const ASN1 = require('@ldapjs/asn1').Ber
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function EqualityFilter (options) {
|
||||
parents.EqualityFilter.call(this, options)
|
||||
}
|
||||
util.inherits(EqualityFilter, parents.EqualityFilter)
|
||||
Filter.mixin(EqualityFilter)
|
||||
module.exports = EqualityFilter
|
||||
|
||||
EqualityFilter.prototype.matches = function (target, strictAttrCase) {
|
||||
assert.object(target, 'target')
|
||||
|
||||
const tv = parents.getAttrValue({ sourceObject: target, attributeName: this.attribute, strictCase: strictAttrCase })
|
||||
let value = this.value
|
||||
|
||||
if (this.attribute.toLowerCase() === 'objectclass') {
|
||||
/*
|
||||
* Perform case-insensitive match for objectClass since nearly every LDAP
|
||||
* implementation behaves in this manner.
|
||||
*/
|
||||
value = value.toLowerCase()
|
||||
return parents.testValues({
|
||||
rule: function (v) {
|
||||
return value === v.toLowerCase()
|
||||
},
|
||||
value: tv
|
||||
})
|
||||
} else {
|
||||
return parents.testValues({
|
||||
rule: function (v) {
|
||||
return value === v
|
||||
},
|
||||
value: tv
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
EqualityFilter.prototype.parse = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
this.attribute = ber.readString().toLowerCase()
|
||||
this.value = ber.readString(ASN1.OctetString, true)
|
||||
|
||||
if (this.attribute === 'objectclass') { this.value = this.value.toLowerCase() }
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
EqualityFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
ber.writeString(this.attribute)
|
||||
ber.writeBuffer(this.raw, ASN1.OctetString)
|
||||
|
||||
return ber
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
/**
|
||||
* RFC 2254 Escaping of filter strings
|
||||
*
|
||||
* Raw Escaped
|
||||
* (o=Parens (R Us)) (o=Parens \28R Us\29)
|
||||
* (cn=star*) (cn=star\2A)
|
||||
* (filename=C:\MyFile) (filename=C:\5cMyFile)
|
||||
*
|
||||
* Use substr_filter to avoid having * ecsaped.
|
||||
*
|
||||
* @author [Austin King](https://github.com/ozten)
|
||||
*/
|
||||
exports.escape = function (inp) {
|
||||
if (typeof (inp) === 'string') {
|
||||
let esc = ''
|
||||
for (let i = 0; i < inp.length; i++) {
|
||||
switch (inp[i]) {
|
||||
case '*':
|
||||
esc += '\\2a'
|
||||
break
|
||||
case '(':
|
||||
esc += '\\28'
|
||||
break
|
||||
case ')':
|
||||
esc += '\\29'
|
||||
break
|
||||
case '\\':
|
||||
esc += '\\5c'
|
||||
break
|
||||
case '\0':
|
||||
esc += '\\00'
|
||||
break
|
||||
default:
|
||||
esc += inp[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
return esc
|
||||
} else {
|
||||
return inp
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
// THIS IS A STUB!
|
||||
//
|
||||
// ldapjs does not support server side extensible matching.
|
||||
// This class exists only for the client to send them.
|
||||
|
||||
/// --- API
|
||||
|
||||
function ExtensibleFilter (options) {
|
||||
parents.ExtensibleFilter.call(this, options)
|
||||
}
|
||||
util.inherits(ExtensibleFilter, parents.ExtensibleFilter)
|
||||
Filter.mixin(ExtensibleFilter)
|
||||
module.exports = ExtensibleFilter
|
||||
|
||||
ExtensibleFilter.prototype.parse = function (ber) {
|
||||
const end = ber.offset + ber.length
|
||||
while (ber.offset < end) {
|
||||
const tag = ber.peek()
|
||||
switch (tag) {
|
||||
case 0x81:
|
||||
this.rule = ber.readString(tag)
|
||||
break
|
||||
case 0x82:
|
||||
this.matchType = ber.readString(tag)
|
||||
break
|
||||
case 0x83:
|
||||
this.value = ber.readString(tag)
|
||||
break
|
||||
case 0x84:
|
||||
this.dnAttributes = ber.readBoolean(tag)
|
||||
break
|
||||
default:
|
||||
throw new Error('Invalid ext_match filter type: 0x' + tag.toString(16))
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
ExtensibleFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
if (this.rule) { ber.writeString(this.rule, 0x81) }
|
||||
if (this.matchType) { ber.writeString(this.matchType, 0x82) }
|
||||
|
||||
ber.writeString(this.value, 0x83)
|
||||
if (this.dnAttributes) { ber.writeBoolean(this.dnAttributes, 0x84) }
|
||||
|
||||
return ber
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
// var assert = require('assert')
|
||||
|
||||
const Protocol = require('@ldapjs/protocol')
|
||||
|
||||
/// --- Globals
|
||||
|
||||
const TYPES = {
|
||||
and: Protocol.search.FILTER_AND,
|
||||
or: Protocol.search.FILTER_OR,
|
||||
not: Protocol.search.FILTER_NOT,
|
||||
equal: Protocol.search.FILTER_EQUALITY,
|
||||
substring: Protocol.search.FILTER_SUBSTRINGS,
|
||||
ge: Protocol.search.FILTER_GE,
|
||||
le: Protocol.search.FILTER_LE,
|
||||
present: Protocol.search.FILTER_PRESENT,
|
||||
approx: Protocol.search.FILTER_APPROX,
|
||||
ext: Protocol.search.FILTER_EXT
|
||||
}
|
||||
|
||||
/// --- API
|
||||
|
||||
function isFilter (filter) {
|
||||
if (!filter || typeof (filter) !== 'object') {
|
||||
return false
|
||||
}
|
||||
// Do our best to duck-type it
|
||||
if (typeof (filter.toBer) === 'function' &&
|
||||
typeof (filter.matches) === 'function' &&
|
||||
TYPES[filter.type] !== undefined) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function isBerWriter (ber) {
|
||||
return Boolean(
|
||||
ber &&
|
||||
typeof (ber) === 'object' &&
|
||||
typeof (ber.startSequence) === 'function' &&
|
||||
typeof (ber.endSequence) === 'function'
|
||||
)
|
||||
}
|
||||
|
||||
function mixin (target) {
|
||||
target.prototype.toBer = function toBer (ber) {
|
||||
if (isBerWriter(ber) === false) { throw new TypeError('ber (BerWriter) required') }
|
||||
|
||||
ber.startSequence(TYPES[this.type])
|
||||
ber = this._toBer(ber)
|
||||
ber.endSequence()
|
||||
return ber
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isFilter: isFilter,
|
||||
mixin: mixin
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function GreaterThanEqualsFilter (options) {
|
||||
parents.GreaterThanEqualsFilter.call(this, options)
|
||||
}
|
||||
util.inherits(GreaterThanEqualsFilter, parents.GreaterThanEqualsFilter)
|
||||
Filter.mixin(GreaterThanEqualsFilter)
|
||||
module.exports = GreaterThanEqualsFilter
|
||||
|
||||
GreaterThanEqualsFilter.prototype.parse = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
this.attribute = ber.readString().toLowerCase()
|
||||
this.value = ber.readString()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
GreaterThanEqualsFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
ber.writeString(this.attribute)
|
||||
ber.writeString(this.value)
|
||||
|
||||
return ber
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
|
||||
const asn1 = require('@ldapjs/asn1')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Protocol = require('@ldapjs/protocol')
|
||||
|
||||
const Filter = require('./filter')
|
||||
const AndFilter = require('./and_filter')
|
||||
const ApproximateFilter = require('./approx_filter')
|
||||
const EqualityFilter = require('./equality_filter')
|
||||
const ExtensibleFilter = require('./ext_filter')
|
||||
const GreaterThanEqualsFilter = require('./ge_filter')
|
||||
const LessThanEqualsFilter = require('./le_filter')
|
||||
const NotFilter = require('./not_filter')
|
||||
const OrFilter = require('./or_filter')
|
||||
const PresenceFilter = require('./presence_filter')
|
||||
const SubstringFilter = require('./substr_filter')
|
||||
|
||||
/// --- Globals
|
||||
|
||||
const BerReader = asn1.BerReader
|
||||
|
||||
/// --- Internal Parsers
|
||||
|
||||
/*
|
||||
* A filter looks like this coming in:
|
||||
* Filter ::= CHOICE {
|
||||
* and [0] SET OF Filter,
|
||||
* or [1] SET OF Filter,
|
||||
* not [2] Filter,
|
||||
* equalityMatch [3] AttributeValueAssertion,
|
||||
* substrings [4] SubstringFilter,
|
||||
* greaterOrEqual [5] AttributeValueAssertion,
|
||||
* lessOrEqual [6] AttributeValueAssertion,
|
||||
* present [7] AttributeType,
|
||||
* approxMatch [8] AttributeValueAssertion,
|
||||
* extensibleMatch [9] MatchingRuleAssertion --v3 only
|
||||
* }
|
||||
*
|
||||
* SubstringFilter ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* SEQUENCE OF CHOICE {
|
||||
* initial [0] IA5String,
|
||||
* any [1] IA5String,
|
||||
* final [2] IA5String
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* The extensibleMatch was added in LDAPv3:
|
||||
*
|
||||
* MatchingRuleAssertion ::= SEQUENCE {
|
||||
* matchingRule [1] MatchingRuleID OPTIONAL,
|
||||
* type [2] AttributeDescription OPTIONAL,
|
||||
* matchValue [3] AssertionValue,
|
||||
* dnAttributes [4] BOOLEAN DEFAULT FALSE
|
||||
* }
|
||||
*/
|
||||
function _parse (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
function parseSet (f) {
|
||||
const end = ber.offset + ber.length
|
||||
while (ber.offset < end) { f.addFilter(_parse(ber)) }
|
||||
}
|
||||
|
||||
let f
|
||||
|
||||
const type = ber.readSequence()
|
||||
switch (type) {
|
||||
case Protocol.search.FILTER_AND:
|
||||
f = new AndFilter()
|
||||
parseSet(f)
|
||||
break
|
||||
|
||||
case Protocol.search.FILTER_APPROX:
|
||||
f = new ApproximateFilter()
|
||||
f.parse(ber)
|
||||
break
|
||||
|
||||
case Protocol.search.FILTER_EQUALITY:
|
||||
f = new EqualityFilter()
|
||||
f.parse(ber)
|
||||
return f
|
||||
|
||||
case Protocol.search.FILTER_EXT:
|
||||
f = new ExtensibleFilter()
|
||||
f.parse(ber)
|
||||
return f
|
||||
|
||||
case Protocol.search.FILTER_GE:
|
||||
f = new GreaterThanEqualsFilter()
|
||||
f.parse(ber)
|
||||
return f
|
||||
|
||||
case Protocol.search.FILTER_LE:
|
||||
f = new LessThanEqualsFilter()
|
||||
f.parse(ber)
|
||||
return f
|
||||
|
||||
case Protocol.search.FILTER_NOT:
|
||||
f = new NotFilter({
|
||||
filter: _parse(ber)
|
||||
})
|
||||
break
|
||||
|
||||
case Protocol.search.FILTER_OR:
|
||||
f = new OrFilter()
|
||||
parseSet(f)
|
||||
break
|
||||
|
||||
case Protocol.search.FILTER_PRESENT:
|
||||
f = new PresenceFilter()
|
||||
f.parse(ber)
|
||||
break
|
||||
|
||||
case Protocol.search.FILTER_SUBSTRINGS:
|
||||
f = new SubstringFilter()
|
||||
f.parse(ber)
|
||||
break
|
||||
|
||||
default:
|
||||
throw new Error('Invalid search filter type: 0x' + type.toString(16))
|
||||
}
|
||||
|
||||
assert.ok(f)
|
||||
return f
|
||||
}
|
||||
|
||||
function cloneFilter (input) {
|
||||
let child
|
||||
if (input.type === 'and' || input.type === 'or') {
|
||||
child = input.filters.map(cloneFilter)
|
||||
} else if (input.type === 'not') {
|
||||
child = cloneFilter(input.filter)
|
||||
}
|
||||
switch (input.type) {
|
||||
case 'and':
|
||||
return new AndFilter({ filters: child })
|
||||
case 'or':
|
||||
return new OrFilter({ filters: child })
|
||||
case 'not':
|
||||
return new NotFilter({ filter: child })
|
||||
case 'equal':
|
||||
return new EqualityFilter(input)
|
||||
case 'substring':
|
||||
return new SubstringFilter(input)
|
||||
case 'ge':
|
||||
return new GreaterThanEqualsFilter(input)
|
||||
case 'le':
|
||||
return new LessThanEqualsFilter(input)
|
||||
case 'present':
|
||||
return new PresenceFilter(input)
|
||||
case 'approx':
|
||||
return new ApproximateFilter(input)
|
||||
case 'ext':
|
||||
return new ExtensibleFilter(input)
|
||||
default:
|
||||
throw new Error('invalid filter type:' + input.type)
|
||||
}
|
||||
}
|
||||
|
||||
function escapedToHex (str) {
|
||||
return str.replace(/\\([0-9a-f](?![0-9a-f])|[^0-9a-f]|$)/gi, function (match, p1) {
|
||||
if (!p1) {
|
||||
return '\\5c'
|
||||
}
|
||||
|
||||
const hexCode = p1.charCodeAt(0).toString(16)
|
||||
return '\\' + hexCode
|
||||
})
|
||||
}
|
||||
|
||||
function parseString (str) {
|
||||
const hexStr = escapedToHex(str)
|
||||
const generic = parents.parse(hexStr)
|
||||
// The filter object(s) return from ldap-filter.parse lack the toBer/parse
|
||||
// decoration that native ldapjs filter possess. cloneFilter adds that back.
|
||||
return cloneFilter(generic)
|
||||
}
|
||||
|
||||
/// --- API
|
||||
|
||||
module.exports = {
|
||||
parse: function (ber) {
|
||||
if (!ber || !(ber instanceof BerReader)) { throw new TypeError('ber (BerReader) required') }
|
||||
|
||||
return _parse(ber)
|
||||
},
|
||||
|
||||
parseString: parseString,
|
||||
|
||||
isFilter: Filter.isFilter,
|
||||
|
||||
AndFilter: AndFilter,
|
||||
ApproximateFilter: ApproximateFilter,
|
||||
EqualityFilter: EqualityFilter,
|
||||
ExtensibleFilter: ExtensibleFilter,
|
||||
GreaterThanEqualsFilter: GreaterThanEqualsFilter,
|
||||
LessThanEqualsFilter: LessThanEqualsFilter,
|
||||
NotFilter: NotFilter,
|
||||
OrFilter: OrFilter,
|
||||
PresenceFilter: PresenceFilter,
|
||||
SubstringFilter: SubstringFilter
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function LessThanEqualsFilter (options) {
|
||||
parents.LessThanEqualsFilter.call(this, options)
|
||||
}
|
||||
util.inherits(LessThanEqualsFilter, parents.LessThanEqualsFilter)
|
||||
Filter.mixin(LessThanEqualsFilter)
|
||||
module.exports = LessThanEqualsFilter
|
||||
|
||||
LessThanEqualsFilter.prototype.parse = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
this.attribute = ber.readString().toLowerCase()
|
||||
this.value = ber.readString()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
LessThanEqualsFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
ber.writeString(this.attribute)
|
||||
ber.writeString(this.value)
|
||||
|
||||
return ber
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function NotFilter (options) {
|
||||
parents.NotFilter.call(this, options)
|
||||
}
|
||||
util.inherits(NotFilter, parents.NotFilter)
|
||||
Filter.mixin(NotFilter)
|
||||
module.exports = NotFilter
|
||||
|
||||
NotFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
return this.filter.toBer(ber)
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function OrFilter (options) {
|
||||
parents.OrFilter.call(this, options)
|
||||
}
|
||||
util.inherits(OrFilter, parents.OrFilter)
|
||||
Filter.mixin(OrFilter)
|
||||
module.exports = OrFilter
|
||||
|
||||
OrFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
this.filters.forEach(function (f) {
|
||||
ber = f.toBer(ber)
|
||||
})
|
||||
|
||||
return ber
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function PresenceFilter (options) {
|
||||
parents.PresenceFilter.call(this, options)
|
||||
}
|
||||
util.inherits(PresenceFilter, parents.PresenceFilter)
|
||||
Filter.mixin(PresenceFilter)
|
||||
module.exports = PresenceFilter
|
||||
|
||||
PresenceFilter.prototype.parse = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
this.attribute =
|
||||
ber.buffer.slice(0, ber.length).toString('utf8').toLowerCase()
|
||||
|
||||
ber._offset += ber.length
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
PresenceFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
for (let i = 0; i < this.attribute.length; i++) { ber.writeByte(this.attribute.charCodeAt(i)) }
|
||||
|
||||
return ber
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
const assert = require('assert')
|
||||
const util = require('util')
|
||||
|
||||
const parents = require('@ldapjs/filter')
|
||||
|
||||
const Filter = require('./filter')
|
||||
|
||||
/// --- API
|
||||
|
||||
function SubstringFilter (options) {
|
||||
parents.SubstringFilter.call(this, options)
|
||||
}
|
||||
util.inherits(SubstringFilter, parents.SubstringFilter)
|
||||
Filter.mixin(SubstringFilter)
|
||||
module.exports = SubstringFilter
|
||||
|
||||
SubstringFilter.prototype.parse = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
this.attribute = ber.readString().toLowerCase()
|
||||
ber.readSequence()
|
||||
const end = ber.offset + ber.length
|
||||
|
||||
while (ber.offset < end) {
|
||||
const tag = ber.peek()
|
||||
switch (tag) {
|
||||
case 0x80: // Initial
|
||||
this.initial = ber.readString(tag)
|
||||
if (this.attribute === 'objectclass') { this.initial = this.initial.toLowerCase() }
|
||||
break
|
||||
case 0x81: { // Any
|
||||
let anyVal = ber.readString(tag)
|
||||
if (this.attribute === 'objectclass') { anyVal = anyVal.toLowerCase() }
|
||||
this.any.push(anyVal)
|
||||
break
|
||||
}
|
||||
case 0x82: // Final
|
||||
this.final = ber.readString(tag)
|
||||
if (this.attribute === 'objectclass') { this.final = this.final.toLowerCase() }
|
||||
break
|
||||
default:
|
||||
throw new Error('Invalid substrings filter type: 0x' + tag.toString(16))
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
SubstringFilter.prototype._toBer = function (ber) {
|
||||
assert.ok(ber)
|
||||
|
||||
ber.writeString(this.attribute)
|
||||
ber.startSequence()
|
||||
|
||||
if (this.initial) { ber.writeString(this.initial, 0x80) }
|
||||
|
||||
if (this.any && this.any.length) {
|
||||
this.any.forEach(function (s) {
|
||||
ber.writeString(s, 0x81)
|
||||
})
|
||||
}
|
||||
|
||||
if (this.final) { ber.writeString(this.final, 0x82) }
|
||||
|
||||
ber.endSequence()
|
||||
|
||||
return ber
|
||||
}
|
|
@ -12,7 +12,7 @@ const controls = require('./controls')
|
|||
const persistentSearch = require('./persistent_search')
|
||||
const dn = require('./dn')
|
||||
const errors = require('./errors')
|
||||
const filters = require('./filters')
|
||||
const filters = require('@ldapjs/filter')
|
||||
const messages = require('./messages')
|
||||
const url = require('./url')
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ const asn1 = require('@ldapjs/asn1')
|
|||
const LDAPMessage = require('./message')
|
||||
// var LDAPResult = require('./result')
|
||||
const dn = require('../dn')
|
||||
const filters = require('../filters')
|
||||
const filters = require('@ldapjs/filter')
|
||||
const Protocol = require('@ldapjs/protocol')
|
||||
|
||||
/// --- Globals
|
||||
|
@ -90,7 +90,7 @@ SearchRequest.prototype._parse = function (ber) {
|
|||
this.timeLimit = ber.readInt()
|
||||
this.typesOnly = ber.readBoolean()
|
||||
|
||||
this.filter = filters.parse(ber)
|
||||
this.filter = filters.parseBer(ber)
|
||||
|
||||
// look for attributes
|
||||
if (ber.peek() === 0x30) {
|
||||
|
@ -119,7 +119,8 @@ SearchRequest.prototype._toBer = function (ber) {
|
|||
ber.writeBoolean(this.typesOnly)
|
||||
|
||||
const f = this.filter || new filters.PresenceFilter({ attribute: 'objectclass' })
|
||||
ber = f.toBer(ber)
|
||||
const filterBer = f.toBer(ber)
|
||||
ber.appendBuffer(filterBer.buffer)
|
||||
|
||||
ber.startSequence(Ber.Sequence | Ber.Constructor)
|
||||
if (this.attributes && this.attributes.length) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
const querystring = require('querystring')
|
||||
const url = require('url')
|
||||
const dn = require('./dn')
|
||||
const filter = require('./filters/')
|
||||
const filter = require('@ldapjs/filter')
|
||||
|
||||
module.exports = {
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
"node": ">=10.13.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ldapjs/asn1": "^1.0.0",
|
||||
"@ldapjs/asn1": "1.2.0",
|
||||
"@ldapjs/controls": "^1.0.0",
|
||||
"@ldapjs/filter": "^1.0.0-rc.1",
|
||||
"@ldapjs/filter": "1.0.0",
|
||||
"@ldapjs/protocol": "^1.0.0",
|
||||
"abstract-logging": "^2.0.0",
|
||||
"assert-plus": "^1.0.0",
|
||||
|
|
|
@ -48,9 +48,9 @@ tap.test('whois works correctly (issue #370)', t => {
|
|||
client.exop('1.3.6.1.4.1.4203.1.11.3', (err, value, res) => {
|
||||
t.error(err)
|
||||
t.ok(value)
|
||||
t.is(value, 'dn:cn=Philip J. Fry,ou=people,dc=planetexpress,dc=com')
|
||||
t.equal(value, 'dn:cn=Philip J. Fry,ou=people,dc=planetexpress,dc=com')
|
||||
t.ok(res)
|
||||
t.is(res.status, 0)
|
||||
t.equal(res.status, 0)
|
||||
|
||||
client.unbind(t.end)
|
||||
})
|
||||
|
@ -74,15 +74,15 @@ tap.test('can access large groups (issue #582)', t => {
|
|||
})
|
||||
response.on('error', t.error)
|
||||
response.on('end', (result) => {
|
||||
t.is(result.status, 0)
|
||||
t.is(results.length === 1, true)
|
||||
t.equal(result.status, 0)
|
||||
t.equal(results.length === 1, true)
|
||||
t.ok(results[0].attributes)
|
||||
|
||||
const memberAttr = results[0].attributes.find(a => a.type === 'member')
|
||||
t.ok(memberAttr)
|
||||
t.ok(memberAttr.vals)
|
||||
t.type(memberAttr.vals, Array)
|
||||
t.is(memberAttr.vals.length, 2000)
|
||||
t.equal(memberAttr.vals.length, 2000)
|
||||
|
||||
client.unbind(t.end)
|
||||
})
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { filters: { EqualityFilter, AndFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
t.ok(new AndFilter())
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new AndFilter()
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
}))
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'zig',
|
||||
value: 'zag'
|
||||
}))
|
||||
t.ok(f)
|
||||
t.equal(f.toString(), '(&(foo=bar)(zig=zag))')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match true', function (t) {
|
||||
const f = new AndFilter()
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
}))
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'zig',
|
||||
value: 'zag'
|
||||
}))
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: 'bar', zig: 'zag' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match false', function (t) {
|
||||
const f = new AndFilter()
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
}))
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'zig',
|
||||
value: 'zag'
|
||||
}))
|
||||
t.ok(f)
|
||||
t.ok(!f.matches({ foo: 'bar', zig: 'zonk' }))
|
||||
t.end()
|
||||
})
|
|
@ -1,85 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { BerReader, BerWriter } = require('@ldapjs/asn1')
|
||||
const { filters: { ApproximateFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
const f = new ApproximateFilter()
|
||||
t.ok(f)
|
||||
t.ok(!f.attribute)
|
||||
t.ok(!f.value)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new ApproximateFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar')
|
||||
t.equal(f.toString(), '(foo~=bar)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = escape value only in toString()', function (t) {
|
||||
const f = new ApproximateFilter({
|
||||
attribute: 'foo',
|
||||
value: 'ba(r)'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'ba(r)')
|
||||
t.equal(f.toString(), '(foo~=ba\\28r\\29)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse ok', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeString('bar')
|
||||
|
||||
const f = new ApproximateFilter()
|
||||
t.ok(f)
|
||||
t.ok(f.parse(new BerReader(writer.buffer)))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse bad', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeInt(20)
|
||||
|
||||
const f = new ApproximateFilter()
|
||||
t.ok(f)
|
||||
try {
|
||||
f.parse(new BerReader(writer.buffer))
|
||||
t.fail('Should have thrown InvalidAsn1Error')
|
||||
} catch (e) {
|
||||
t.equal(e.name, 'InvalidAsn1Error')
|
||||
}
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = to ber uses plain values', function (t) {
|
||||
let f = new ApproximateFilter({
|
||||
attribute: 'foo',
|
||||
value: 'ba(r)'
|
||||
})
|
||||
t.ok(f)
|
||||
const writer = new BerWriter()
|
||||
f.toBer(writer)
|
||||
|
||||
f = new ApproximateFilter()
|
||||
t.ok(f)
|
||||
|
||||
const reader = new BerReader(writer.buffer)
|
||||
reader.readSequence()
|
||||
t.ok(f.parse(reader))
|
||||
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'ba(r)')
|
||||
t.end()
|
||||
})
|
|
@ -1,167 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { BerReader, BerWriter } = require('@ldapjs/asn1')
|
||||
const { filters: { EqualityFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
const f = new EqualityFilter()
|
||||
t.ok(f)
|
||||
t.ok(!f.attribute)
|
||||
t.ok(!f.value)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar')
|
||||
t.equal(f.toString(), '(foo=bar)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = escape value only in toString()', function (t) {
|
||||
const f = new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'ba(r)'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'ba(r)')
|
||||
t.equal(f.toString(), '(foo=ba\\28r\\29)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match true', function (t) {
|
||||
const f = new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: 'bar' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match multiple', function (t) {
|
||||
const f = new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: ['plop', 'bar'] }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match false', function (t) {
|
||||
const f = new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(!f.matches({ foo: 'baz' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse ok', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeString('bar')
|
||||
|
||||
const f = new EqualityFilter()
|
||||
t.ok(f)
|
||||
t.ok(f.parse(new BerReader(writer.buffer)))
|
||||
t.ok(f.matches({ foo: 'bar' }))
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('escape EqualityFilter inputs', function (t) {
|
||||
const f = new EqualityFilter({
|
||||
attribute: '(|(foo',
|
||||
value: 'bar))('
|
||||
})
|
||||
|
||||
t.equal(f.attribute, '(|(foo')
|
||||
t.equal(f.value, 'bar))(')
|
||||
t.equal(f.toString(), '(\\28|\\28foo=bar\\29\\29\\28)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse bad', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeInt(20)
|
||||
|
||||
const f = new EqualityFilter()
|
||||
t.ok(f)
|
||||
try {
|
||||
f.parse(new BerReader(writer.buffer))
|
||||
t.fail('Should have thrown InvalidAsn1Error')
|
||||
} catch (e) {
|
||||
t.equal(e.name, 'InvalidAsn1Error')
|
||||
}
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = to ber uses plain values', function (t) {
|
||||
let f = new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'ba(r)'
|
||||
})
|
||||
t.ok(f)
|
||||
const writer = new BerWriter()
|
||||
f.toBer(writer)
|
||||
|
||||
f = new EqualityFilter()
|
||||
t.ok(f)
|
||||
|
||||
const reader = new BerReader(writer.buffer)
|
||||
reader.readSequence()
|
||||
t.ok(f.parse(reader))
|
||||
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'ba(r)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('handle values passed via buffer', function (t) {
|
||||
const b = Buffer.from([32, 64, 128, 254])
|
||||
const f = new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: b
|
||||
})
|
||||
t.ok(f)
|
||||
|
||||
const writer = new BerWriter()
|
||||
f.toBer(writer)
|
||||
const reader = new BerReader(writer.buffer)
|
||||
reader.readSequence()
|
||||
|
||||
const f2 = new EqualityFilter()
|
||||
t.ok(f2.parse(reader))
|
||||
|
||||
t.equal(f2.value, b.toString())
|
||||
t.equal(f2.raw.length, b.length)
|
||||
for (let i = 0; i < b.length; i++) {
|
||||
t.equal(f2.raw[i], b[i])
|
||||
}
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-277 objectClass should be case-insensitive', function (t) {
|
||||
const f = new EqualityFilter({
|
||||
attribute: 'objectClass',
|
||||
value: 'CaseInsensitiveObj'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ objectClass: 'CaseInsensitiveObj' }))
|
||||
t.ok(f.matches({ OBJECTCLASS: 'CASEINSENSITIVEOBJ' }))
|
||||
t.ok(f.matches({ objectclass: 'caseinsensitiveobj' }))
|
||||
t.ok(!f.matches({ objectclass: 'matchless' }))
|
||||
t.end()
|
||||
})
|
|
@ -1,82 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { filters: { parseString, ExtensibleFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
const f = new ExtensibleFilter()
|
||||
t.ok(f)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new ExtensibleFilter({
|
||||
matchType: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.matchType, 'foo')
|
||||
t.equal(f.value, 'bar')
|
||||
t.equal(f.toString(), '(foo:=bar)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse RFC example 1', function (t) {
|
||||
const f = parseString('(cn:caseExactMatch:=Fred Flintstone)')
|
||||
t.ok(f)
|
||||
t.equal(f.matchType, 'cn')
|
||||
t.equal(f.matchingRule, 'caseExactMatch')
|
||||
t.equal(f.matchValue, 'Fred Flintstone')
|
||||
t.notOk(f.dnAttributes)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse RFC example 2', function (t) {
|
||||
const f = parseString('(cn:=Betty Rubble)')
|
||||
t.ok(f)
|
||||
t.equal(f.matchType, 'cn')
|
||||
t.equal(f.matchValue, 'Betty Rubble')
|
||||
t.notOk(f.dnAttributes)
|
||||
t.notOk(f.matchingRule)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse RFC example 3', function (t) {
|
||||
const f = parseString('(sn:dn:2.4.6.8.10:=Barney Rubble)')
|
||||
t.ok(f)
|
||||
t.equal(f.matchType, 'sn')
|
||||
t.equal(f.matchingRule, '2.4.6.8.10')
|
||||
t.equal(f.matchValue, 'Barney Rubble')
|
||||
t.ok(f.dnAttributes)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse RFC example 3', function (t) {
|
||||
const f = parseString('(o:dn:=Ace Industry)')
|
||||
t.ok(f)
|
||||
t.equal(f.matchType, 'o')
|
||||
t.notOk(f.matchingRule)
|
||||
t.equal(f.matchValue, 'Ace Industry')
|
||||
t.ok(f.dnAttributes)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse RFC example 4', function (t) {
|
||||
const f = parseString('(:1.2.3:=Wilma Flintstone)')
|
||||
t.ok(f)
|
||||
t.notOk(f.matchType)
|
||||
t.equal(f.matchingRule, '1.2.3')
|
||||
t.equal(f.matchValue, 'Wilma Flintstone')
|
||||
t.notOk(f.dnAttributes)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse RFC example 5', function (t) {
|
||||
const f = parseString('(:DN:2.4.6.8.10:=Dino)')
|
||||
t.ok(f)
|
||||
t.notOk(f.matchType)
|
||||
t.equal(f.matchingRule, '2.4.6.8.10')
|
||||
t.equal(f.matchValue, 'Dino')
|
||||
t.ok(f.dnAttributes)
|
||||
t.end()
|
||||
})
|
|
@ -1,116 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { BerReader, BerWriter } = require('@ldapjs/asn1')
|
||||
const { filters: { GreaterThanEqualsFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
const f = new GreaterThanEqualsFilter()
|
||||
t.ok(f)
|
||||
t.ok(!f.attribute)
|
||||
t.ok(!f.value)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new GreaterThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar')
|
||||
t.equal(f.toString(), '(foo>=bar)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = escape value only in toString()', function (t) {
|
||||
const f = new GreaterThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'ba(r)'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'ba(r)')
|
||||
t.equal(f.toString(), '(foo>=ba\\28r\\29)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match true', function (t) {
|
||||
const f = new GreaterThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: 'baz' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match multiple', function (t) {
|
||||
const f = new GreaterThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: ['beuha', 'baz'] }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match false', function (t) {
|
||||
const f = new GreaterThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(!f.matches({ foo: 'abc' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse ok', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeString('bar')
|
||||
|
||||
const f = new GreaterThanEqualsFilter()
|
||||
t.ok(f)
|
||||
t.ok(f.parse(new BerReader(writer.buffer)))
|
||||
t.ok(f.matches({ foo: 'bar' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse bad', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeInt(20)
|
||||
|
||||
const f = new GreaterThanEqualsFilter()
|
||||
t.ok(f)
|
||||
try {
|
||||
f.parse(new BerReader(writer.buffer))
|
||||
t.fail('Should have thrown InvalidAsn1Error')
|
||||
} catch (e) {
|
||||
t.equal(e.name, 'InvalidAsn1Error')
|
||||
}
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = to ber uses plain values', function (t) {
|
||||
let f = new GreaterThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'ba(r)'
|
||||
})
|
||||
t.ok(f)
|
||||
const writer = new BerWriter()
|
||||
f.toBer(writer)
|
||||
|
||||
f = new GreaterThanEqualsFilter()
|
||||
t.ok(f)
|
||||
|
||||
const reader = new BerReader(writer.buffer)
|
||||
reader.readSequence()
|
||||
t.ok(f.parse(reader))
|
||||
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'ba(r)')
|
||||
t.end()
|
||||
})
|
|
@ -1,116 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { BerReader, BerWriter } = require('@ldapjs/asn1')
|
||||
const { filters: { LessThanEqualsFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
const f = new LessThanEqualsFilter()
|
||||
t.ok(f)
|
||||
t.ok(!f.attribute)
|
||||
t.ok(!f.value)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new LessThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar')
|
||||
t.equal(f.toString(), '(foo<=bar)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = escape value only in toString()', function (t) {
|
||||
const f = new LessThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'ba(r)'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'ba(r)')
|
||||
t.equal(f.toString(), '(foo<=ba\\28r\\29)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match true', function (t) {
|
||||
const f = new LessThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: 'abc' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match multiple', function (t) {
|
||||
const f = new LessThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: ['abc', 'beuha'] }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match false', function (t) {
|
||||
const f = new LessThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(!f.matches({ foo: 'baz' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse ok', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeString('bar')
|
||||
|
||||
const f = new LessThanEqualsFilter()
|
||||
t.ok(f)
|
||||
t.ok(f.parse(new BerReader(writer.buffer)))
|
||||
t.ok(f.matches({ foo: 'bar' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse bad', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeInt(20)
|
||||
|
||||
const f = new LessThanEqualsFilter()
|
||||
t.ok(f)
|
||||
try {
|
||||
f.parse(new BerReader(writer.buffer))
|
||||
t.fail('Should have thrown InvalidAsn1Error')
|
||||
} catch (e) {
|
||||
t.equal(e.name, 'InvalidAsn1Error')
|
||||
}
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = to ber uses plain values', function (t) {
|
||||
let f = new LessThanEqualsFilter({
|
||||
attribute: 'foo',
|
||||
value: 'ba(r)'
|
||||
})
|
||||
t.ok(f)
|
||||
const writer = new BerWriter()
|
||||
f.toBer(writer)
|
||||
|
||||
f = new LessThanEqualsFilter()
|
||||
t.ok(f)
|
||||
|
||||
const reader = new BerReader(writer.buffer)
|
||||
reader.readSequence()
|
||||
t.ok(f.parse(reader))
|
||||
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'ba(r)')
|
||||
t.end()
|
||||
})
|
|
@ -1,45 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { filters: { EqualityFilter, NotFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
t.ok(new NotFilter())
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new NotFilter({
|
||||
filter: new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.toString(), '(!(foo=bar))')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match true', function (t) {
|
||||
const f = new NotFilter({
|
||||
filter: new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: 'baz' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match false', function (t) {
|
||||
const f = new NotFilter({
|
||||
filter: new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
})
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(!f.matches({ foo: 'bar' }))
|
||||
t.end()
|
||||
})
|
|
@ -1,54 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { filters: { EqualityFilter, OrFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
t.ok(new OrFilter())
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new OrFilter()
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
}))
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'zig',
|
||||
value: 'zag'
|
||||
}))
|
||||
t.ok(f)
|
||||
t.equal(f.toString(), '(|(foo=bar)(zig=zag))')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match true', function (t) {
|
||||
const f = new OrFilter()
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
}))
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'zig',
|
||||
value: 'zag'
|
||||
}))
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: 'bar', zig: 'zonk' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match false', function (t) {
|
||||
const f = new OrFilter()
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'foo',
|
||||
value: 'bar'
|
||||
}))
|
||||
f.addFilter(new EqualityFilter({
|
||||
attribute: 'zig',
|
||||
value: 'zag'
|
||||
}))
|
||||
t.ok(f)
|
||||
t.ok(!f.matches({ foo: 'baz', zig: 'zonk' }))
|
||||
t.end()
|
||||
})
|
|
@ -1,141 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { parseFilter: parse } = require('../../lib')
|
||||
|
||||
test('GH-48 XML Strings in filter', function (t) {
|
||||
const str = '(&(CentralUIEnrollments=\\<mydoc\\>*)(objectClass=User))'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.ok(f.filters)
|
||||
t.equal(f.filters.length, 2)
|
||||
f.filters.forEach(function (filter) {
|
||||
t.ok(filter.attribute)
|
||||
})
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-50 = in filter', function (t) {
|
||||
const str = '(uniquemember=uuid=930896af-bf8c-48d4-885c-6573a94b1853, ' +
|
||||
'ou=users, o=smartdc)'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'uniquemember')
|
||||
t.equal(f.value,
|
||||
'uuid=930896af-bf8c-48d4-885c-6573a94b1853, ou=users, o=smartdc')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('convert to hex code', function (t) {
|
||||
const str = 'foo=bar\\(abcd\\e\\fg\\h\\69\\a'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar(abcdefghia')
|
||||
t.equal(f.toString(), '(foo=bar\\28abcdefghia)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('( in filter', function (t) {
|
||||
const str = '(foo=bar\\()'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar(')
|
||||
t.equal(f.toString(), '(foo=bar\\28)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test(') in filter', function (t) {
|
||||
const str = '(foo=bar\\))'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar)')
|
||||
t.equal(f.toString(), '(foo=bar\\29)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('\\ in filter', function (t) {
|
||||
const str = '(foo=bar\\\\)'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar\\')
|
||||
t.equal(f.toString(), '(foo=bar\\5c)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('not escaped \\ at end of filter', function (t) {
|
||||
const str = 'foo=bar\\'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar\\')
|
||||
t.equal(f.toString(), '(foo=bar\\5c)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('* in equality filter', function (t) {
|
||||
const str = '(foo=bar\\*)'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.value, 'bar*')
|
||||
t.equal(f.toString(), '(foo=bar\\2a)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('* substr filter (prefix)', function (t) {
|
||||
const str = '(foo=bar*)'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.initial, 'bar')
|
||||
t.equal(f.toString(), '(foo=bar*)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-53 NotFilter', function (t) {
|
||||
const str = '(&(objectClass=person)(!(objectClass=shadowAccount)))'
|
||||
const f = parse(str)
|
||||
t.ok(f)
|
||||
t.equal(f.type, 'and')
|
||||
t.equal(f.filters.length, 2)
|
||||
t.equal(f.filters[0].type, 'equal')
|
||||
t.equal(f.filters[1].type, 'not')
|
||||
t.equal(f.filters[1].filter.type, 'equal')
|
||||
t.equal(f.filters[1].filter.attribute, 'objectClass')
|
||||
t.equal(f.filters[1].filter.value, 'shadowAccount')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('presence filter', function (t) {
|
||||
const f = parse('(foo=*)')
|
||||
t.ok(f)
|
||||
t.equal(f.type, 'present')
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.toString(), '(foo=*)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('bogus filter', function (t) {
|
||||
t.throws(function () {
|
||||
parse('foo>1')
|
||||
})
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('bogus filter !=', function (t) {
|
||||
t.throws(function () {
|
||||
parse('foo!=1')
|
||||
})
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('mismatched parens', function (t) {
|
||||
t.throws(function () {
|
||||
parse('(&(foo=bar)(!(state=done))')
|
||||
})
|
||||
t.end()
|
||||
})
|
|
@ -1,83 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { BerReader, BerWriter } = require('@ldapjs/asn1')
|
||||
const { filters: { PresenceFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
const f = new PresenceFilter()
|
||||
t.ok(f)
|
||||
t.ok(!f.attribute)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new PresenceFilter({
|
||||
attribute: 'foo'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.toString(), '(foo=*)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = escape value only in toString()', function (t) {
|
||||
const f = new PresenceFilter({
|
||||
attribute: 'fo)o'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'fo)o')
|
||||
t.equal(f.toString(), '(fo\\29o=*)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match true', function (t) {
|
||||
const f = new PresenceFilter({
|
||||
attribute: 'foo'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: 'bar' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match false', function (t) {
|
||||
const f = new PresenceFilter({
|
||||
attribute: 'foo'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(!f.matches({ bar: 'foo' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse ok', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo', 0x87)
|
||||
|
||||
const f = new PresenceFilter()
|
||||
t.ok(f)
|
||||
|
||||
const reader = new BerReader(writer.buffer)
|
||||
reader.readSequence()
|
||||
t.ok(f.parse(reader))
|
||||
t.ok(f.matches({ foo: 'bar' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = to ber uses plain values', function (t) {
|
||||
let f = new PresenceFilter({
|
||||
attribute: 'f(o)o'
|
||||
})
|
||||
t.ok(f)
|
||||
const writer = new BerWriter()
|
||||
f.toBer(writer)
|
||||
|
||||
f = new PresenceFilter()
|
||||
t.ok(f)
|
||||
|
||||
const reader = new BerReader(writer.buffer)
|
||||
reader.readSequence()
|
||||
t.ok(f.parse(reader))
|
||||
|
||||
t.equal(f.attribute, 'f(o)o')
|
||||
t.end()
|
||||
})
|
|
@ -1,152 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { BerReader, BerWriter } = require('@ldapjs/asn1')
|
||||
const { filters: { SubstringFilter } } = require('../../lib')
|
||||
|
||||
test('Construct no args', function (t) {
|
||||
const f = new SubstringFilter()
|
||||
t.ok(f)
|
||||
t.ok(!f.attribute)
|
||||
t.ok(!f.value)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Construct args', function (t) {
|
||||
const f = new SubstringFilter({
|
||||
attribute: 'foo',
|
||||
initial: 'bar',
|
||||
any: ['zig', 'zag'],
|
||||
final: 'baz'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'foo')
|
||||
t.equal(f.initial, 'bar')
|
||||
t.equal(f.any.length, 2)
|
||||
t.equal(f.any[0], 'zig')
|
||||
t.equal(f.any[1], 'zag')
|
||||
t.equal(f.final, 'baz')
|
||||
t.equal(f.toString(), '(foo=bar*zig*zag*baz)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = escape value only in toString()', function (t) {
|
||||
const f = new SubstringFilter({
|
||||
attribute: 'fo(o',
|
||||
initial: 'ba(r)',
|
||||
any: ['zi)g', 'z(ag'],
|
||||
final: '(baz)'
|
||||
})
|
||||
t.ok(f)
|
||||
t.equal(f.attribute, 'fo(o')
|
||||
t.equal(f.initial, 'ba(r)')
|
||||
t.equal(f.any.length, 2)
|
||||
t.equal(f.any[0], 'zi)g')
|
||||
t.equal(f.any[1], 'z(ag')
|
||||
t.equal(f.final, '(baz)')
|
||||
t.equal(f.toString(), '(fo\\28o=ba\\28r\\29*zi\\29g*z\\28ag*\\28baz\\29)')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match true', function (t) {
|
||||
const f = new SubstringFilter({
|
||||
attribute: 'foo',
|
||||
initial: 'bar',
|
||||
any: ['zig', 'zag'],
|
||||
final: 'baz'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: 'barmoozigbarzagblahbaz' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match false', function (t) {
|
||||
const f = new SubstringFilter({
|
||||
attribute: 'foo',
|
||||
initial: 'bar',
|
||||
foo: ['zig', 'zag'],
|
||||
final: 'baz'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(!f.matches({ foo: 'bafmoozigbarzagblahbaz' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('match any', function (t) {
|
||||
const f = new SubstringFilter({
|
||||
attribute: 'foo',
|
||||
initial: 'bar'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ foo: ['beuha', 'barista'] }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = escape for regex in matches', function (t) {
|
||||
const f = new SubstringFilter({
|
||||
attribute: 'fo(o',
|
||||
initial: 'ba(r)',
|
||||
any: ['zi)g', 'z(ag'],
|
||||
final: '(baz)'
|
||||
})
|
||||
t.ok(f)
|
||||
t.ok(f.matches({ 'fo(o': ['ba(r)_zi)g-z(ag~(baz)'] }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse ok', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.startSequence()
|
||||
writer.writeString('bar', 0x80)
|
||||
writer.writeString('bad', 0x81)
|
||||
writer.writeString('baz', 0x82)
|
||||
writer.endSequence()
|
||||
const f = new SubstringFilter()
|
||||
t.ok(f)
|
||||
t.ok(f.parse(new BerReader(writer.buffer)))
|
||||
t.ok(f.matches({ foo: 'bargoobadgoobaz' }))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('parse bad', function (t) {
|
||||
const writer = new BerWriter()
|
||||
writer.writeString('foo')
|
||||
writer.writeInt(20)
|
||||
|
||||
const f = new SubstringFilter()
|
||||
t.ok(f)
|
||||
try {
|
||||
f.parse(new BerReader(writer.buffer))
|
||||
t.fail('Should have thrown InvalidAsn1Error')
|
||||
} catch (e) {
|
||||
}
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('GH-109 = to ber uses plain values', function (t) {
|
||||
let f = new SubstringFilter({
|
||||
attribute: 'fo(o',
|
||||
initial: 'ba(r)',
|
||||
any: ['zi)g', 'z(ag'],
|
||||
final: '(baz)'
|
||||
})
|
||||
t.ok(f)
|
||||
const writer = new BerWriter()
|
||||
f.toBer(writer)
|
||||
|
||||
f = new SubstringFilter()
|
||||
t.ok(f)
|
||||
|
||||
const reader = new BerReader(writer.buffer)
|
||||
reader.readSequence()
|
||||
t.ok(f.parse(reader))
|
||||
|
||||
t.equal(f.attribute, 'fo(o')
|
||||
t.equal(f.initial, 'ba(r)')
|
||||
t.equal(f.any.length, 2)
|
||||
t.equal(f.any[0], 'zi)g')
|
||||
t.equal(f.any[1], 'z(ag')
|
||||
t.equal(f.final, '(baz)')
|
||||
t.end()
|
||||
})
|
|
@ -30,6 +30,10 @@ tap.beforeEach((t) => {
|
|||
t.context.socketPath = getSock()
|
||||
t.context.suffix = suffix
|
||||
|
||||
server.on('error', err => {
|
||||
server.close(() => reject(err))
|
||||
})
|
||||
|
||||
server.bind('cn=root', function (req, res, next) {
|
||||
res.end()
|
||||
return next()
|
||||
|
@ -57,6 +61,9 @@ tap.beforeEach((t) => {
|
|||
socketPath: t.context.socketPath
|
||||
})
|
||||
|
||||
t.context.client.on('error', (err) => {
|
||||
t.context.server.close(() => reject(err))
|
||||
})
|
||||
t.context.client.on('connectError', (err) => {
|
||||
t.context.server.close(() => reject(err))
|
||||
})
|
||||
|
@ -80,7 +87,7 @@ tap.afterEach((t) => {
|
|||
})
|
||||
})
|
||||
|
||||
tap.test('Evolution search filter (GH-3)', function (t) {
|
||||
tap.test('Evolution search filter (GH-3)', { only: true }, function (t) {
|
||||
// This is what Evolution sends, when searching for a contact 'ogo'. Wow.
|
||||
const filter =
|
||||
'(|(cn=ogo*)(givenname=ogo*)(sn=ogo*)(mail=ogo*)(member=ogo*)' +
|
||||
|
|
|
@ -33,14 +33,16 @@ test('parse', function (t) {
|
|||
value: 'foo@bar.com'
|
||||
})
|
||||
|
||||
let ber = new BerWriter()
|
||||
const ber = new BerWriter()
|
||||
ber.writeString('cn=foo, o=test')
|
||||
ber.writeEnumeration(0)
|
||||
ber.writeEnumeration(0)
|
||||
ber.writeInt(1)
|
||||
ber.writeInt(2)
|
||||
ber.writeBoolean(false)
|
||||
ber = f.toBer(ber)
|
||||
|
||||
const eqBer = f.toBer()
|
||||
ber.appendBuffer(eqBer.buffer)
|
||||
|
||||
const req = new SearchRequest()
|
||||
t.ok(req._parse(new BerReader(ber.buffer)))
|
||||
|
|
Loading…
Reference in New Issue