diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..41306be --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,23 @@ +If you found a bug in python-ldap, or would request a new feature, +this is the place to let us know. + +Please describe the issue and your environment here. + +--- + +Issue description: + + + + + + +Steps to reproduce: + + + +Operating system: + +Python version: + +python-ldap version: diff --git a/.gitignore b/.gitignore index 03b366d..4e261ca 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,6 @@ __pycache__/ build/ dist/ PKG-INFO + +# generated in the sample workflow +/__venv__/ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..0866c8e --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,10 @@ +Thank you for your interest in python-ldap! + +If you wish to help, detailed instructions are in `Doc/contributing.rst`_, +and in `online documentation`_. + +.. _Doc/contributing.rst: Doc/contributing.rst +.. _online documentation: http://python-ldap.readthedocs.io/en/latest/contributing.html + + +Open-source veretans should find no surprises there. diff --git a/Doc/.gitignore b/Doc/.gitignore index a485625..5e13421 100644 --- a/Doc/.gitignore +++ b/Doc/.gitignore @@ -1 +1,2 @@ -/_build +/_build/ +/.build/ diff --git a/Doc/contributing.rst b/Doc/contributing.rst new file mode 100644 index 0000000..3a904d3 --- /dev/null +++ b/Doc/contributing.rst @@ -0,0 +1,266 @@ +.. highlight:: console + +Contributing to python-ldap +*************************** + +Thank you for your interest in python-ldap! +If you'd like to contribute (be it code, documentation, maintenance effort, +or anything else), this guide is for you. + + +Communication +============= + +Always keep in mind that python-ldap is developed and maintained by volunteers. +We're happy to share our work, and to work with you to make the library better, +but (until you pay someone), there's obligation to provide assistance. + +So, keep it friendly, respectful, and supportive! + + +Mailing list +------------ + +Discussion about the use and future of python-ldap occurs in +the ``python-ldap@python.org`` mailing list. + +It's also the channel to use if documentation (including this guide) is not +clear to you. +Do try searching around before you ask on the list, though! + +You can `subscribe or unsubscribe`_ to this list or browse the `list archive`_. + +.. _subscribe or unsubscribe: https://mail.python.org/mailman/listinfo/python-ldap +.. _list archive: https://mail.python.org/pipermail/python-ldap/ + + +Issues +------ + +Please report bugs, missing features and other issues to `the bug tracker`_ +at GitHub. You will need a GitHub account for that. + +If you prefer not to open a GitHub account, you're always welcome to use the +mailing list. + + +Security Contact +---------------- + +If you found a security issue that should not be discussed publicly, +please e-mail the maintainer at ``pviktori@redhat.com``. +If required, write to coordinate a more secure channel. + +All other communication should be public. + + +Process for Code contributions +============================== + +If you're used to open-source Python development with Git, here's the gist: + +* ``git clone https://github.com/python-ldap/python-ldap`` +* Use GitHub for `the bug tracker`_ and pull requests. +* Run tests with `tox`_; ignore Python interpreters you don't have locally. + +.. _the bug tracker: https://github.com/python-ldap/python-ldap/issues +.. _tox: https://tox.readthedocs.io/en/latest/ + +Or, if you prefer to avoid closed-source services: + +* ``git clone https://pagure.io/python-ldap`` +* Send bug reports and patches to the mailing list. +* Run tests with `tox`_; ignore Python interpreters you don't have locally. +* Read the documentation directly at `Read the Docs`_. + +.. _Read the Docs: http://python-ldap.readthedocs.io/ + +If you're new to some aspect of the project, you're welcome to use (or adapt) +the workflow below. + + +Sample workflow +--------------- + +We assume that, as a user of python-ldap you're not new to software +development in general, so these instructions are terse. +If you need additional detail, please do ask on the mailing list. + +.. note:: + + The following instructions are for Linux. + If you can translate them to another system, please contribute your + translation! + + +Install `Git`_ and `tox`_. + +Clone the repository:: + + $ git clone https://github.com/python-ldap/python-ldap + $ cd python-ldap + +Create a `virtual environment`_ to ensure you in-development python-ldap won't +affect the rest of your system:: + + $ python3 -m venv __venv__ + +(For Python 2, install `virtualenv`_ and use it instead of ``python3 -m venv``.) + +.. _git: https://git-scm.com/ +.. _virtual environment: https://docs.python.org/3/library/venv.html +.. _virtualenv: https://virtualenv.pypa.io/en/stable/ + +Activate the virtual environment:: + + $ source __venv__/bin/activate + +Install python-ldap to it in `editable mode`_:: + + (__venv__)$ python -m pip install -e . + +This way, importing a Python module from python-ldap will directly +use the code from your source tree. +If you change C code, you will still need to recompile +(using the ``pip install`` command again). + +.. _editable mode: https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs + +Change the code as desired. + + +To run tests, install and run `tox`_:: + + (__venv__)$ python -m pip install tox + (__venv__)$ tox --skip-missing-interpreters + +This will run tests on all supported versions of Python that you have +installed, skipping the ones you don't. +To run a subset of test environments, run for example:: + + (__venv__)$ tox -e py27,py36 + +In addition to ``pyXY`` environments, we have extra environments +for checking things independent of the Python version: + +* ``doc`` checks syntax and spelling of the documentation +* ``coverage-report`` generates a test coverage report for Python code. + It must be used last, e.g. ``tox -e py27,py36,coverage-report``. + + +When your change is ready, commit to Git, and submit a pull request on GitHub. +You can take a look at the `committer instructions`_ to see what we are looking +for in a pull request. + +If you don't want to open a GitHub account, please send patches as attachments +to the python-ldap mailing list. + + +.. _additional tests: + +Additional tests and scripts +============================ + +We use several specialized tools for debugging and maintenance. + +Make targets +------------ + +``make lcov-open`` + Generate and view test coverage for C code. + Requires ``make`` and ``lcov``. + +``make scan-build`` + Run static analysis. Requires ``clang``. + + +Reference leak tests +-------------------- + +Reference leak tests require a *pydebug* build of CPython and `pytest`_ with +`pytest-leaks`_ plugin. A *pydebug* build has a global reference counter, which +keeps track of all reference increments and decrements. The leak plugin runs +each test multiple times and checks if the reference count increases. + +.. _pytest: https://docs.pytest.org/en/latest/ +.. _pytest-leaks: https://pypi.python.org/pypi/pytest-leaks + +Download and compile the *pydebug* build:: + + $ curl -O https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tar.xz + $ tar xJf Python-3.6.3.tar.xz + $ cd Python-3.6.3 + $ ./configure --with-pydebug + $ make + +Create a virtual environment with the *pydebug* build:: + + $ ./python -m venv /tmp/refleak + $ /tmp/refleak/bin/pip install pytest pytest-leaks + +Run reference leak tests:: + + $ cd path/to/python-ldap + $ /tmp/refleak/bin/pip install --upgrade . + $ /tmp/refleak/bin/pytest -v -R: Tests/t_*.py + +Run ``/tmp/refleak/bin/pip install --upgrade .`` every time a file outside +of ``Tests/`` is modified. + + +.. _committer instructions: + +Instructions for core committers +================================ + +If you have the authority (and responsibility) of merging changes from others, +remember: + +* All code changes need to be reviewed by someone other than the author. + +* Tests must always pass. New features without tests shall *not* pass review. + +* Make sure commit messages don't use GitHub-specific link syntax. + Use the full URL, e.g. ``https://github.com/python-ldap/python-ldap/issues/50`` + instead of ``#20``. + + * Exception: it's fine to use the short form in the summary line of a merge + commit, if the full URL appears later. + * It's OK to use shortcuts in GitHub *discussions*, where they are not + hashed into immutable history. + +* Make a merge commit if the contribution contains several well-isolated + separate commits with good descriptions. Use *squash-and-merge* (or + *fast-forward* from a command line) for all other cases. + +* It's OK to push small changes into a pull request. If you do this, document + what you have done (so the contributor can learn for the future), and get + their :abbr:`ACK (confirmation)` before merging. + +* When squashing, do edit commit messages to add references to the pull request + and relevant discussions/issues, and to conform to Git best practices. + + * Consider making the summary line suitable for the CHANGES document, + and starting it with a prefix like ``Lib:`` or ``Tests:``. + +* Push to Pagure as well. + +If you have good reason to break the “rules”, go ahead and break them, +but mention why. + + +Instructions for release managers +================================= + +If you are tasked with releasing python-ldap, remember to: + +* Bump all instances of the version number. +* Go through all changes since last version, and add them to ``CHANGES``. +* Run :ref:`additional tests` as appropriate, fix any regressions. +* Merge all that (using pull requests). +* Run ``python setup.py sdist``, and smoke-test the resulting package + (install in a clean virtual environment, import ``ldap``). +* Create Git tag ``python-ldap-{version}``, and push it to GitHub and Pagure. +* Release the ``sdist`` on PyPI. +* Announce the release on the mailing list. + Mention the Git hash. diff --git a/Doc/faq.rst b/Doc/faq.rst index 58bb81e..ef479a8 100644 --- a/Doc/faq.rst +++ b/Doc/faq.rst @@ -35,41 +35,41 @@ Usage **Q**: My code imports module ``_ldap``. -That used to work but from version 2.0.0pre that does not work anymore? +That used to work, but after an upgrade it does not work anymore. Why? - **A**: Despite some outdated programming examples the extension module - ``_ldap`` **MUST NOT** be imported directly unless - you really know what you're doing (e.g. for internal regression testing). + **A**: Despite some outdated programming examples, the extension module + ``_ldap`` **MUST NOT** be imported directly, unless you really know what + you're doing (e.g. for internal regression testing). - Import ``ldap`` instead which is a Python wrapper around ``_ldap`` + Import ``ldap`` instead, which is a Python wrapper around ``_ldap`` providing the full functionality. **Q**: My script bound to MS Active Directory but a a search operation results -in an exception :exc:`ldap.OPERATIONS_ERROR` with the diagnostic messages text -"In order to perform this operation a successful bind must be -completed on the connection." +in the exception :exc:`ldap.OPERATIONS_ERROR` with the diagnostic messages text +“In order to perform this operation a successful bind must be +completed on the connection.” What's happening here? - **A**: When searching from the domain level MS AD returns referrals (search continuations) + **A**: When searching from the domain level, MS AD returns referrals (search continuations) for some objects to indicate to the client where to look for these objects. - Client-chasing of referrals is a broken concept since LDAPv3 does not specify + Client-chasing of referrals is a broken concept, since LDAPv3 does not specify which credentials to use when chasing the referral. Windows clients are supposed - to simply use their Windows credentials but this does not work in general when + to simply use their Windows credentials, but this does not work in general when chasing referrals received from and pointing to arbitrary LDAP servers. - Therefore per default ``libldap`` automatically chases the referrals + Therefore, per default, ``libldap`` automatically chases the referrals internally with an *anonymous* access which fails with MS AD. - So best thing is to switch this behaviour off:: + So, the best thing to do is to switch this behaviour off:: l = ldap.initialize('ldap://foobar') l.set_option(ldap.OPT_REFERRALS,0) -**Q**: Why am I seeing ``ldap.SUCCESS`` traceback as output? +**Q**: Why am I seeing a ``ldap.SUCCESS`` traceback as output? - **A**: Most likely you are using one of the non-synchronous calls, and probably + **A**: Most likely, you are using one of the non-synchronous calls, and probably mean to be using a synchronous call - (see detailed explanation in :ref:`sending-ldap-requests`. + (see detailed explanation in :ref:`sending-ldap-requests`). **Q**: Can I use LDAPv2 via python-ldap? @@ -87,13 +87,14 @@ Installing **Q**: Does it work with Windows 32? - **A**: You can find links to pre-compiled packages for Win32 on the - :ref:`Download information` page. + **A**: Yes. You can find links to unofficial pre-compiled packages + for Windows on the :ref:`installing` page. **Q**: Can python-ldap be built against OpenLDAP 2.3 libs or older? - **A**: No, for recent python-ldap 2.4.x the OpenLDAP 2.4 client libs or newer are required. + **A**: No. + The needed minimal version of OpenLDAP is documented in :ref:`build prerequisites`. Patched builds of python-ldap linked to older libs are not supported by the python-ldap project. @@ -123,8 +124,8 @@ telling Lib/ldap.py and Lib/ldap/schema.py are not found:: --global-option="-I$(xcrun --show-sdk-path)/usr/include/sasl" -**Q**: While importing module ldap some shared lib files are not found. -Error message looks similar to this:: +**Q**: While importing module ``ldap``, some shared lib files are not found. +The error message looks similar to this:: ImportError: ld.so.1: /usr/local/bin/python: fatal: liblber.so.2: open failed: No such file or directory @@ -133,9 +134,9 @@ Error message looks similar to this:: **A1**: You need to make sure that the path to ``liblber.so.2`` and ``libldap.so.2`` is in your ``LD_LIBRARY_PATH`` environment variable. - **A2**: Alternatively if you're on Linux you can add the path to + **A2**: Alternatively, if you're on Linux, you can add the path to ``liblber.so.2`` and ``libldap.so.2`` to ``/etc/ld.so.conf`` - and invoke command ``ldconfig`` afterwards. + and invoke the command ``ldconfig`` afterwards. @@ -151,32 +152,32 @@ Historic But the python-ldap docs say LDAP libs 2.x are needed. I'm confused! Short answer: - See answer above and :ref:`download information` for + See answer above and the :ref:`installing` page for a more recent version. Long answer: E.g. some Win32 DLLs floating around for download are based on the old Umich LDAP code which is not maintained anymore for - ``many`` years! Last Umich 3.3 release was 1997 if I remember correctly. + *many* years! Last Umich 3.3 release was 1997 if I remember correctly. The OpenLDAP project took over the Umich code and started releasing OpenLDAP 1.x series mainly fixing bugs and doing some improvements - to the database backend. Still only LDAPv2 was supported at server + to the database backend. Still, only LDAPv2 was supported at server and client side. (Many commercial vendors also derived their products from the Umich code.) - OpenLDAP 2.x is a full-fledged LDAPv3 implementation. Still it has + OpenLDAP 2.x is a full-fledged LDAPv3 implementation. It has its roots in Umich code but has many more features/improvements. -**Q**: While importing module ldap there are undefined references reported. -Error message looks similar to this:: +**Q**: While importing module ``ldap``, there are undefined references reported. +The error message looks similar to this:: ImportError: /usr/local/lib/libldap.so.2: undefined symbol: res_query .. - **A**: Especially on older Linux systems you might have to explicitly link + **A**: Especially on older Linux systems, you might have to explicitly link against ``libresolv``. Tweak ``setup.cfg`` to contain this line:: diff --git a/Doc/index.rst b/Doc/index.rst index 6d2f1ac..2c5b24e 100644 --- a/Doc/index.rst +++ b/Doc/index.rst @@ -5,30 +5,39 @@ python-ldap What is python-ldap? -------------------- -* python-ldap provides an object-oriented API to access LDAP - directory servers from `Python`_ programs. -* For LDAP operations the module wraps `OpenLDAP`_'s - client library *libldap* for that purpose. -* Additionally the package contains modules for other LDAP-related stuff: +python-ldap provides an object-oriented API to access `LDAP`_ +directory servers from `Python`_ programs. - * LDIF +For LDAP operations the module wraps `OpenLDAP`_'s +client library, *libldap*. + +Additionally, the package contains modules for other LDAP-related stuff: + + * `LDIF`_ parsing and generation * LDAP URLs * LDAPv3 subschema +.. _LDAP: https://en.wikipedia.org/wiki/Ldap .. _Python: https://www.python.org/ .. _OpenLDAP: https://www.openldap.org/ +.. _LDIF: https://en.wikipedia.org/wiki/LDIF Get it! ------- -:ref:`Download information` is available for several platforms. +:ref:`Installation instructions ` are available for +several platforms. + +Source code can be obtained using Git:: + + git clone https://github.com/python-ldap/python-ldap Mailing list ------------ -Discussion about the use and future of Python-LDAP occurs in +Discussion about the use and future of python-ldap occurs in the ``python-ldap@python.org`` mailing list. You can `subscribe or unsubscribe`_ to this list or browse the `list archive`_. @@ -43,7 +52,7 @@ Documentation The documentation for python-ldap 3.x is hosted at `Read the Docs`_. You can switch between versions of the library, or download PDF or HTML -versions for offline use, using the right sidebar. +versions for offline use, using the sidebar on the right. Documentation for some older versions is available for download at the `GitHub release page`_. @@ -61,6 +70,7 @@ Contents installing.rst reference/index.rst resources.rst + contributing.rst faq.rst diff --git a/Doc/installing.rst b/Doc/installing.rst index 2ea5594..3907539 100644 --- a/Doc/installing.rst +++ b/Doc/installing.rst @@ -1,4 +1,4 @@ -.. _Download information: +.. _installing: Installing python-ldap ###################### @@ -7,7 +7,7 @@ Installing from PyPI ==================== The preferred point for downloading the “official” source distribution -is now the `PyPI repository`_ which supports installing via `pip`_. +is the `PyPI repository`_ which supports installing via `pip`_. For example:: python -m pip install python-ldap @@ -15,7 +15,7 @@ For example:: .. _PyPI repository: https://pypi.python.org/pypi/python-ldap/ .. _pip: https://pip.pypa.io/en/stable/ -For installing from PyPI, you will need the :ref:`build prerequisites` +For installing from PyPI, you will need the same :ref:`build prerequisites` as when installing from source. We do not currently provide pre-built packages (wheels). @@ -64,8 +64,8 @@ Unofficial packages for Windows are available on `Christoph Gohlke's page `_. -`FreeBSD `_ +------------------------------------- The CVS repository of FreeBSD contains the package `py-ldap `_ @@ -81,6 +81,8 @@ You can install directly with pip:: --global-option="-I$(xcrun --show-sdk-path)/usr/include/sasl" +.. _install-source: + Installing from Source ====================== @@ -94,7 +96,7 @@ From a source repository:: If you have more than one Python interpreter installed locally, you should use the same one you plan to use python-ldap with. -See further instructions can be found in `Setuptools documentation`_. +Further instructions can be found in `Setuptools documentation`_. .. _Setuptools documentation: https://docs.python.org/3/distributing/index.html @@ -109,16 +111,17 @@ The following software packages are required to be installed on the local system when building python-ldap: - `Python`_ version 2.7, or 3.3 or later including its development files +- C compiler corresponding to your Python version (on Linux, it is usually ``gcc``) - `OpenLDAP`_ client libs version 2.4.11 or later It is not possible and not supported to build with prior versions. - `OpenSSL`_ (optional) -- `cyrus-sasl`_ (optional) +- `Cyrus SASL`_ (optional) - Kerberos libraries, MIT or Heimdal (optional) .. _Python: https://www.python.org/ .. _OpenLDAP: https://www.openldap.org/ .. _OpenSSL: https://www.openssl.org/ -.. _cyrus-sasl: https://www.cyrusimap.org/sasl/ +.. _Cyrus SASL: https://www.cyrusimap.org/sasl/ setup.cfg @@ -126,9 +129,9 @@ setup.cfg The file setup.cfg allows to set some build and installation parameters for reflecting the local installation of required -software packages. Only section [_ldap] is described here. -More information about other sections can be found in the -documentation of Python's DistUtils. +software packages. Only section ``[_ldap]`` is described here. +More information about other sections can be found in +`Setuptools documentation`_. .. data:: library_dirs @@ -148,9 +151,10 @@ documentation of Python's DistUtils. .. data:: extra_objects -.. _libs-used-label: +.. _libs-used-label: + Libraries used --------------- @@ -159,7 +163,7 @@ Libraries used .. data:: ldap_r :noindex: - The LDAP protocol library of OpenLDAP. ldap_r is the reentrant version + The LDAP protocol library of OpenLDAP. ``ldap_r`` is the reentrant version and should be preferred. .. data:: lber @@ -170,25 +174,25 @@ Libraries used .. data:: sasl2 :noindex: - The Cyrus-SASL library if needed and present during build + The Cyrus-SASL library (optional) .. data:: ssl :noindex: - The SSL/TLS library of OpenSSL if needed and present during build + The SSL/TLS library of OpenSSL (optional) .. data:: crypto :noindex: - The basic cryptographic library of OpenSSL if needed and present during build + The basic cryptographic library of OpenSSL (optional) Example ------- The following example is for a full-featured build (including SSL and SASL support) of python-ldap with OpenLDAP installed in a different prefix directory -(here /opt/openldap-2.4) and SASL header files found in /usr/include/sasl. -Debugging symbols are preserved with compile option -g. +(here ``/opt/openldap-2.4``) and SASL header files found in /usr/include/sasl. +Debugging symbols are preserved with compile option ``-g``. :: diff --git a/Doc/spelling_wordlist.txt b/Doc/spelling_wordlist.txt index 39df00f..95a5df6 100644 --- a/Doc/spelling_wordlist.txt +++ b/Doc/spelling_wordlist.txt @@ -29,9 +29,11 @@ clientctrls conf controlType controlValue +committers +CPython criticality cryptographic -cyrus +Cyrus defresult dereferenced dereferencing @@ -91,7 +93,8 @@ objectClass oc oid oids -openldap +OpenLDAP +Pagure postalAddress pre previousDN @@ -148,3 +151,4 @@ userPassword usr uuids whitespace +workflow diff --git a/INSTALL b/INSTALL index 57b00b7..0475a2f 100644 --- a/INSTALL +++ b/INSTALL @@ -1,60 +1,9 @@ ------------------------------- -Installing python-ldap ------------------------------- - -Prerequisites: - - Required: - - - Python 2.3 or newer (see http://www.python.org) - - - OpenLDAP 2.4.11+ client libs (see http://www.openldap.org) - It is not possible and not supported - by the python-ldap project to build with prior versions. - - Optional dependencies of OpenLDAP libs: - - - Cyrus SASL 2.1.x or newer (see http://asg.web.cmu.edu/sasl/sasl-library.html) - - - OpenSSL 0.9.7 or newer (see http://www.openssl.org) - - - MIT Kerberos or heimdal libs - Quick build instructions: + edit setup.cfg (see Build/ for platform-specific examples) python setup.py build python setup.py install --------------------- -Reference leak tests --------------------- - -Reference leak tests require a pydebug build of CPython and pytest with -pytest-leaks plugin. A pydebug build has a global reference counter, which -keeps track of all reference increments and decrements. The leak plugin runs -each tests multiple times and checks if the reference count increases. - -Download and compile pydebug build ----------------------------------- - -- curl -O https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tar.xz -- tar xJf Python-3.6.3.tar.xz -- cd Python-3.6.3 -- ./configure --with-pydebug -- make - -Create virtual env ------------------- - -- ./python -m venv /tmp/refleak -- /tmp/refleak/bin/pip install pytest pytest-leaks - -Run refleak tests ------------------ - -- cd path/to/python-ldap -- /tmp/refleak/bin/pip install --upgrade . -- /tmp/refleak/bin/pytest -v -R: Tests/t_*.py +Detailed instructions are in Doc/installing.rst, or online at: -Run ``/tmp/refleak/bin/pip install --upgrade .`` every time a file outside -of ``Tests/`` is modified. \ No newline at end of file + http://python-ldap.readthedocs.io/en/latest/installing.html