Всем доброго времени суток!
Хочу поделиться небольшим скриптом на Python, который написал в свободное время, изучая Python. Так как совсем недавно непосредственно работал с Zimbra, за неимением клиента на Python и за отсутствием в Zimbra WSDL, было решено написать таковой (скрипт).
Возможности скрипта на данный момент:
— аутентификация при помощи мейла/пароля
— пре-аутентификация при помощи мейла/доменного ключа
— аутентификация с административными привилегиями
— работа с Zimbra через прокси сервер, с возможной аутентификацией на прокси
— обработка исключений и ошибок Zimbra, конвертация в питоновское исключение с сохранением информации от Zimbra
Запланировано:
— предоставление собственного API для работы с Zimbra (на подобие ZClient), дабы пользователям не заморачиваться с непосредственной работой с XML.
Примеры использования
Некоторые примеры доступны в исходниках на GitHub.
Работа с Zimbra Soap API
Немного информации в рамках данной статьи о том, как работает SOAP в Zimbra. Zimbra предоставляет два различных endpoint'a (не знаю какой термин по-русски здесь подойдет): /service/soap для работы с правами пользователя, и /service/admin/soap для работы с правами администратора. В заголовке каждого сообщения должен присутствовать элемент контекста (Context). В нем передается идентификатор сессии, токен и прочие мета-данные. При запросе аутентификации передается пустой контекст.
Неприятные особенности Zimbra Soap API и SOAPpy
— особенность Zimbra Soap API:
при работе с Soap API в каждом запросе/ответе может присутствовать идентификатор сессии (sessionId), при аутентификации он также присутствует в теле ответа. Само по себе это особых проблем не представляет, но при работе с SOAPpy это создает определенную проблему, о чем далее.
— особенности SOAPpy:
проблема 1: при разборе SOAP сообщения, SOAPpy пытается построить дерево с сылками на другие элементы внутри документа, при чем делает это в не зависимости от вашего на то желания. Ссылки определяются наличием в элементе атрибута id, который должен ссылаться на соответствующие идентификаторы других элементов. Естесственно, возникает конфликт при обработке успешного ответа аутентификации от Zimbra, и SOAPpy жалуется на повторяющийся идентификатор. В SOAPpy нет возможности отключить построение этого дерева ссылок.
проблема 2: не удалось заставить SOAPpy аутентифицироваться на прокси.
Возможные решения проблемы 1:
— вариант 1:
забыть про SOAPpy и написать полностью свой парсер и билдер, что присутствовало в скрипте до перехода на SOAPpy, возвращаться обратно на велосипед как-то не очень хотелось.
— вариант 2:
отписать свой парсер для аутентификации, далее продолжать работать с SOAPpy. Вариант отпал, так как не хотелось разводить зоопарк.
— вариант 3:
подобрать другую библиотеку для работы с SOAP, которая работает без WSDL. Честно сказать, было лень их тестировать, поэтому было решено остановиться на SOAPpy, немного доработав напильником.
Решение проблемы 1:
Во-первых, необходимо переписать SOAPpy.SOAPParser, исключив построение дерева ссылок, так как в Zimbra данный функционал вообще ни к чему.
Дублировать код не хотелось, поэтому поступил дешево и сердито, обнуляя внутренний массив с уже разобранными идентификаторами при каждой обработке узла документа.
Далее, необходимо заменить метод SOAPpy.Parser._parseSOAP, инициализируя упрощенный парсер вместо оригинального, все остальное, в общем-то, остается без изменений. Замена функции происходит перед отправкой запроса.
Решение проблемы 2:
Чтобы заставить SOAPpy общаться через прокси с аутентификацией, пришлось заменить класс SOAPpy.Client.HTTPTransport на свой, в котором HTTP общение реализовано с помощью urllib2, в которой легко использовать поддержку прокси и прочие плюшки, благо SOAPpy позволяет без проблем предоставлять свою реализацию транспорта.
Вот, собственно говоря, и все. Данная библиотека ни на что особенное не претендует, тем не менее надеюсь хоть кому-то может пригодиться.
Немного информации, а также возможность сообщить об ошибке, есть на GitHub.
Если есть конструктивные комментарии по улучшению скрипта, буду рад выслушать.
Ответить в комментариях не могу за не имением инвайта, если кто пригласит, буду благодарен.
Хочу поделиться небольшим скриптом на Python, который написал в свободное время, изучая Python. Так как совсем недавно непосредственно работал с Zimbra, за неимением клиента на Python и за отсутствием в Zimbra WSDL, было решено написать таковой (скрипт).
Возможности скрипта на данный момент:
— аутентификация при помощи мейла/пароля
— пре-аутентификация при помощи мейла/доменного ключа
— аутентификация с административными привилегиями
— работа с Zimbra через прокси сервер, с возможной аутентификацией на прокси
— обработка исключений и ошибок Zimbra, конвертация в питоновское исключение с сохранением информации от Zimbra
Запланировано:
— предоставление собственного API для работы с Zimbra (на подобие ZClient), дабы пользователям не заморачиваться с непосредственной работой с XML.
Примеры использования
Некоторые примеры доступны в исходниках на GitHub.
Работа с Zimbra Soap API
Немного информации в рамках данной статьи о том, как работает SOAP в Zimbra. Zimbra предоставляет два различных endpoint'a (не знаю какой термин по-русски здесь подойдет): /service/soap для работы с правами пользователя, и /service/admin/soap для работы с правами администратора. В заголовке каждого сообщения должен присутствовать элемент контекста (Context). В нем передается идентификатор сессии, токен и прочие мета-данные. При запросе аутентификации передается пустой контекст.
Неприятные особенности Zimbra Soap API и SOAPpy
— особенность Zimbra Soap API:
при работе с Soap API в каждом запросе/ответе может присутствовать идентификатор сессии (sessionId), при аутентификации он также присутствует в теле ответа. Само по себе это особых проблем не представляет, но при работе с SOAPpy это создает определенную проблему, о чем далее.
— особенности SOAPpy:
проблема 1: при разборе SOAP сообщения, SOAPpy пытается построить дерево с сылками на другие элементы внутри документа, при чем делает это в не зависимости от вашего на то желания. Ссылки определяются наличием в элементе атрибута id, который должен ссылаться на соответствующие идентификаторы других элементов. Естесственно, возникает конфликт при обработке успешного ответа аутентификации от Zimbra, и SOAPpy жалуется на повторяющийся идентификатор. В SOAPpy нет возможности отключить построение этого дерева ссылок.
проблема 2: не удалось заставить SOAPpy аутентифицироваться на прокси.
Возможные решения проблемы 1:
— вариант 1:
забыть про SOAPpy и написать полностью свой парсер и билдер, что присутствовало в скрипте до перехода на SOAPpy, возвращаться обратно на велосипед как-то не очень хотелось.
— вариант 2:
отписать свой парсер для аутентификации, далее продолжать работать с SOAPpy. Вариант отпал, так как не хотелось разводить зоопарк.
— вариант 3:
подобрать другую библиотеку для работы с SOAP, которая работает без WSDL. Честно сказать, было лень их тестировать, поэтому было решено остановиться на SOAPpy, немного доработав напильником.
Решение проблемы 1:
Во-первых, необходимо переписать SOAPpy.SOAPParser, исключив построение дерева ссылок, так как в Zimbra данный функционал вообще ни к чему.
Дублировать код не хотелось, поэтому поступил дешево и сердито, обнуляя внутренний массив с уже разобранными идентификаторами при каждой обработке узла документа.
Далее, необходимо заменить метод SOAPpy.Parser._parseSOAP, инициализируя упрощенный парсер вместо оригинального, все остальное, в общем-то, остается без изменений. Замена функции происходит перед отправкой запроса.
Решение проблемы 2:
Чтобы заставить SOAPpy общаться через прокси с аутентификацией, пришлось заменить класс SOAPpy.Client.HTTPTransport на свой, в котором HTTP общение реализовано с помощью urllib2, в которой легко использовать поддержку прокси и прочие плюшки, благо SOAPpy позволяет без проблем предоставлять свою реализацию транспорта.
Вот, собственно говоря, и все. Данная библиотека ни на что особенное не претендует, тем не менее надеюсь хоть кому-то может пригодиться.
Немного информации, а также возможность сообщить об ошибке, есть на GitHub.
Если есть конструктивные комментарии по улучшению скрипта, буду рад выслушать.
Ответить в комментариях не могу за не имением инвайта, если кто пригласит, буду благодарен.