Skip to content

parse_uds_directory silently drops directoryUri when CUCM sets the schema-legal exist attribute #39

Description

@bandrel

Summary

parse_uds_directory() extracts each field with a bare-tag regex:

m = re.search(rf'<{tag}>([^<]*)</{tag}>', block)

That requires the element to have no attributes. But the v14 schema gives <directoryUri> an optional exist attribute — from UDS-xsd-14.zip, xsd/pub/users/users.get.xsd:

<xs:complexType name="directoryUri">
    <xs:simpleContent>
        <xs:extension base="xs:string">
            <xs:attribute type="xs:boolean" name="exist" use="optional"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

So when CUCM returns <directoryUri exist="true">alice@corp.example</directoryUri>, the regex does not match and the field is silently recorded as ''.

Reproduced

xml = ('<users totalCount="1"><user><userName>alice</userName>'
       '<directoryUri exist="true">alice@corp.example</directoryUri>'
       '</user></users>')
thief.parse_uds_directory(xml)[0]['directory_uri']
# -> ''   (expected 'alice@corp.example')

Impact

directoryUri is the user's SIP/Jabber URI — one of the higher-value fields in the corporate directory harvest, since it is frequently the address used for Jabber/Webex targeting and often mirrors the mail address. Losing it is silent: --directory and --userenum still report success, the CSV still has a directory_uri column, and it is simply empty for every record. An operator has no signal that the field was dropped rather than genuinely unset on the cluster, and the existing tests all use attribute-free fixtures so nothing catches it.

Whether it bites depends on whether the target cluster populates exist, which is exactly the kind of thing that varies between engagements — so this can look fine in testing and lose data in the field.

Fix

Allow attributes on the element, anchored with \b so a short tag cannot match a longer one that merely starts with it (<id> vs <identityHint>):

m = re.search(rf'<{tag}\b[^>]*>([^<]*)</{tag}>', block)

This affects only the extraction pattern, and applies to every field in _UDS_DIRECTORY_FIELDS rather than special-casing directoryUri, since the schema permits attributes generally.

Notes

Found during the UDS schema-conformance audit (#33, #35, #36, #37) by a code-quality review pass against the official v14 XSDs. Pre-existing — not introduced by that work — but the same class of defect, so it is fixed in the same PR with regression tests covering the attribute case, the no-attribute case, and the <id>/<identityHint> prefix-collision guard.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions