{ "info": { "author": "Rasmus Munk", "author_email": "munk1@live.dk", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "Intended Audience :: Science/Research", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": ".. image:: https://travis-ci.org/rasmunk/ldap_hooks.svg?branch=master\n :target: https://travis-ci.org/rasmunk/ldap_hooks\n\n==========\nldap_hooks\n==========\n\nA Jupyter Spawner hook for creating LDAP DIT entries via `pre_spawn_hook\n`_\n\n------------\nInstallation\n------------\n\nInstallation from pypi::\n\n pip install ldap-hooks\n\nInstallation from local git repository::\n\n cd ldap_hooks\n pip install .\n\n-------------\nConfiguration\n-------------\n\nYou should edit your ``jupyterhub_config.py`` config file to set a particular\npre_spawn_hook, E.g::\n\n from ldap_hooks import hello_hook\n\n c.Spawner.pre_spawn_hook = hello_hook\n\nBeyond this, a set of connection parameters must be set in order for\nthe JupyterHub server to be able to interact with the designated LDAP host::\n\n from ldap_hooks import LDAP\n\n LDAP.url = \"openldap\"\n LDAP.user = \"cn=admin,dc=example,dc=org\"\n LDAP.password = \"dummyldap_password\"\n LDAP.base_dn = \"dc=example,dc=org\"\n\nThe user's permissions here depend on whether the hook is just\nextracting information, or is creating entries as well.\n\nThe hooks that this library provides can be found below.\n\nBy default, any of these hooks are called by the Spawner\nwith the following syntax::\n\n def hook(spawner):\n # Do stuff inside the hook\n return True\n\nThat is, the hook expects that the current ``spawner`` instance\nis passed to it, which it can subsequently use to access\nproperties of it, such as the ``user`` instance.\n\n=====================\nsetup_ldap_entry_hook\n=====================\n\nThis hook enables that the Spawner will submit/create an LDAP entry\nbefore the spawner starts the notebook. It is activate by setting the\nfollowing parameter in the JupyterHub config::\n\n from ldap_hooks import setup_ldap_entry_hook\n\n c.Spawner.pre_spawn_hook = setup_ldap_entry_hook\n\nIn addition, the hook requires a number of a parameters to be configured\nbefore it will work as intended.\n\n-------------------\nBasic Configuration\n-------------------\n\nFirst, to defined the following options, the ``LDAP`` class\nmust be imported into the ``jupyterhub_config.py`` file::\n\n from ldap_hooks import LDAP\n\nWith this completed, the `submit_spawner_attribute` must be set,\nthis must point to the variable path in the spawner instance\nwhere it can find the `Distinguished Name String (DN) `_ value.\nThis string value makes up the entry that is to be submitted to the LDAP DIT,\nE.g::\n\n # Retrieve the Distinguished Name from the 'spawner.user.data' variable\n LDAP.submit_spawner_attribute = 'user.data'\n\nIn addition if this variable is of a dictionary structure,\na tuple row can be specified to define the set of keys that\nshould be used to extract the Distinguished Name value.\nFor instance, if the value is in the\nspawner.user.data['User']['DN'] structure::\n\n # Extract the Distinguished Name string from the\n # spawner.user.data['User']['DN'] path.\n LDAP.submit_spawner_attribute = 'user.data'\n LDAP.submit_spawner_attribute_keys = ('User', 'DN')\n\nIf this extracted string is formatted in a way that is\nincorrectly seperated, the ``replace_object_with`` parameter can be\nused to fix this, E.g.::\n\n # Prepare LDAP DN object entry\n LDAP.replace_object_with = {'/': '+'}\n # Does the following replacement\n # /telephoneNumber=23012303403/SN=My Surname/CN=a-new-user\n # +telephoneNumber=23012303403+SN=My Surname+CN=a-new-user\n\nBy default the ``name_strip_chars`` parameter is\ndefined to strip extra characters that are either\npre or postfixed to the DN::\n\n # Default value\n LDAP.name_strip_chars = ['/', '+', '*', ',', '.', '!', ' ']\n\nWhich means that it will automatically strip\nthe prefixed ``+`` from the ``replace_object_with`` output.\n\nBefore the hook can submit the prepared DN,\nit first has to know which `Structural ObjectClass `_\nshould be used to create the entry with.\nBeyond at least one required Structural ObjectClass,\na list of additional `Auxiliary ObjectClasses `_\ncan be specified as well.\nAll of which must be set via the ``object_classes`` parameter, E.g::\n\n # Structural 'Person'\n LDAP.object_classes = ['Person']\n\nAny specified object class must be supported as\npart of the specified ``LDAP.url`` server schema.\n\nBeyond the ``object_classes``, the hook also\nprovides a parameter to specify additional object\nattributes to submittet DN entry::\n\n LDAP.object_attributes = {'description': 'A default person account',\n 'surname': 'MySurname'}\n\nDuplicate entries can be default not exist in the LDAP DIT,\ntherefore any duplicate DN submission will fail.\nBy default the hook will search the DIT for\nan entry that matches every attribute of the DN string,\nif such an entry exists, the hook will simply stop before\nattempting to submit it. This behaviour can be customised\nvia the ``unique_object_attributes`` parameter as shown in\nthe \"Extra Features\" section.\n\n\n--------------\nExtra Features\n--------------\n\n^^^^^^^^^^^^^^^^^^^^^^^^\nunique_object_attributes\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nIt is possible to specify special attributes\nthat the hook should use for this search via\nthe ``unique_object_attributes`` parameter::\n\n # Optional parameter\n LDAP.unique_object_attributes = ['surname']\n\nNow the hook will search for if an entry with ``object_classes``\nexists, if so it will stop the submission.\n\n^^^^^^^^^^^^^^^^^^^^^^\nset_spawner_attributes\n^^^^^^^^^^^^^^^^^^^^^^\n\nUse this to set JupyterHub Spawner attributes.\nFor instance set an environment variable of the Spawned notebooks::\n\n # Set Spawned Notebook environment vars\n LDAP.set_spawner_attributes = {\n 'environment': {'ENV_VAR': 'Hello from LDAP Hook'}\n }\n\n^^^^^^^^^^^^^^^^^^^^^^^^\nsearch_attribute_queries\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nUse this to define a list of LDAP search operations to extract a\nlist of attributes from the existing DIT which can subsequntly be used\nto perform some subsequent operation on the extracted attributes,\nor share them with the ``set_spawner_attributes`` or ``object_attributes``\nvia the ``dynamic_attributes`` definition.\n\nFor instance, extract the ``uidNumber`` attribute from the LDAP DIT\nwhich has the ``x-nextUserIdentifier`` objectclass::\n\n LDAP.search_attribute_queries = [\n {'search_base': LDAP.base_dn,\n 'search_filter': '(objectclass=X-nextUserIdentifier)',\n 'attributes': ['uidNumber']}\n ]\n\n^^^^^^^^^^^^^^^^^^^^^^^^\nsearch_result_operations\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nUse this to perform an operation action on extracted attributes of the\n``search_attribute_queries``. The specific action must be defined\nas a LDAP.SEARCH_RESULT_OPERATION_ACTIONS.\nFor instance, increment the value of the extracted ``uidNumber`` attribute by 1,\nfor this particular action, it is required that the ``modify_dn`` key is also\nprovided since it defines the Distinguished Name that should be used to select that attribute to be incremented in the DIT::\n\n modify_dn = 'cn=uidNumber' + ',' + LDAP.base_dn\n LDAP.search_result_operation = {'uidNumber': {'action': INCREMENT_ATTRIBUTE,\n 'modify_dn': modify_dn}}\n\nThis will produce an atomic modify-increment to the value of the ``cn=uidNumber,dc=example,dc=org``.\n\n^^^^^^^^^^^^^^^^^^\ndynamic_attributes\n^^^^^^^^^^^^^^^^^^\n\nTo format ``set_spawner_attributes`` and ``object_attributes`` with dynamic attributes,\nsuch as the result of an LDAP.SEARCH_RESULT_OPERATION_ACTIONS or values provided\nby a ``submit_spawner_attribute`` dictionary. The ``dynamic_attributes`` can\nbe used to format such attributes. For instance, if the ``set_spawner_attributes``\ndefines attributes that expects formatting of the 'emailAddress' and 'uidNumber'::\n\n LDAP.set_spawner_attributes = {\n 'environment': {'NB_USER': '{emailAddress}',\n 'NB_UID': '{uidNumber}'},\n }\n\nThe ``dynamic_attributes`` can provide these as follows::\n\n LDAP.dynamic_attributes = {\n 'emailAddress': SPAWNER_SUBMIT_DATA,\n 'uidNumber': LDAP_SEARCH_ATTRIBUTE_QUERY\n }\n\nWhere the values of the keys define how and where the attribute values should be extracted.\nThe specified value must be defined as a LDAP.DYNAMIC_ATTRIBUTE_METHODS.\n\nIn addition these ``dynamic_attributes`` are made available to the defined ``object_attributes``.\nFor example::\n\n LDAP.object_attributes = {'uidNumber': '{uidNumber}',\n 'homeDirectory': '/home/{emailAddress}'}\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/rasmunk/ldap_hooks", "keywords": "Web,JupyterHub,Spawner,Hook", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "ldap-hooks", "package_url": "https://pypi.org/project/ldap-hooks/", "platform": "", "project_url": "https://pypi.org/project/ldap-hooks/", "project_urls": { "Homepage": "https://github.com/rasmunk/ldap_hooks" }, "release_url": "https://pypi.org/project/ldap-hooks/0.0.3/", "requires_dist": [ "ldap3 (>=2.5.2)", "traitlets (>=4.3.2)", "tornado (==5.1.1)", "gen (>=0.1)" ], "requires_python": "", "summary": "A set of Jupyter Spawner\u00a0pre_spawn_hooks for creating/retrieving LDAP DIT entries during spawn", "version": "0.0.3" }, "last_serial": 5314636, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "13e0079bc218c491c3f83f9441454585", "sha256": "4c2cf2892e73613f3477bc79bdb39b691d41a5ae852b1ee030ba6cbec8305e6c" }, "downloads": -1, "filename": "ldap_hooks-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "13e0079bc218c491c3f83f9441454585", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 10955, "upload_time": "2019-04-08T15:10:50", "url": "https://files.pythonhosted.org/packages/36/2a/4db5702de0e078bbf976baec4450eb72d28609760a98369847993321b96b/ldap_hooks-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "75acdb943f48c448dabfcfcd8f146b68", "sha256": "dc27ea6e4bf8696cc9ec9541aa449b68129b1056eb24e31e688869ff79b3a968" }, "downloads": -1, "filename": "ldap_hooks-0.0.1.tar.gz", "has_sig": false, "md5_digest": "75acdb943f48c448dabfcfcd8f146b68", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11823, "upload_time": "2019-04-08T15:10:52", "url": "https://files.pythonhosted.org/packages/9c/49/e42680b8750243caf3f2da29ff1f924d08b6f90a48396eba06deb95321a5/ldap_hooks-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "74d667f0cd558cb85d7987f583646d00", "sha256": "6723c5eb2d2a7ce28d7166add414cf9403946e1d5be931f0cc24070b39d5b666" }, "downloads": -1, "filename": "ldap_hooks-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "74d667f0cd558cb85d7987f583646d00", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15687, "upload_time": "2019-05-02T12:56:25", "url": "https://files.pythonhosted.org/packages/18/00/40db58634ad966ac827fb5f5a8f7290e8130f7e311f51613f78ecfed89c8/ldap_hooks-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f24f8bfd7652edc9c560da4c19cce636", "sha256": "09d684fa32a35d90629325e80daa0c5b7bbfc2aa9679d46bda313a48b4feb4b5" }, "downloads": -1, "filename": "ldap_hooks-0.0.2.tar.gz", "has_sig": false, "md5_digest": "f24f8bfd7652edc9c560da4c19cce636", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16728, "upload_time": "2019-05-02T12:56:26", "url": "https://files.pythonhosted.org/packages/d9/1a/fdbdf479ae564031c2159c5f176f6befd401e28d680906f5ba1814af4a82/ldap_hooks-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "7b1694d5985942618f6adab0e4fe05b7", "sha256": "38f47c8e19f05718d779cbc48a1396821cc2021c4f02b2c8e26483fd3d2984fb" }, "downloads": -1, "filename": "ldap_hooks-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "7b1694d5985942618f6adab0e4fe05b7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16361, "upload_time": "2019-05-24T21:47:22", "url": "https://files.pythonhosted.org/packages/81/4a/539164e939977a3691d9533289ca2108c38399f59ebff1ba23b9a760a5e1/ldap_hooks-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ee670205721bc9fa0acc26d59b6cf3e7", "sha256": "25af801c0bca70064c1f56c8ac91a03bd9f48536391c8d4a0b620e39cc339d83" }, "downloads": -1, "filename": "ldap_hooks-0.0.3.tar.gz", "has_sig": false, "md5_digest": "ee670205721bc9fa0acc26d59b6cf3e7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17503, "upload_time": "2019-05-24T21:47:24", "url": "https://files.pythonhosted.org/packages/d9/2e/2029a8fba7b87c7dfaa4839f9e3ab0405e3b7d2992a7c94c1c2ca6a8c3fa/ldap_hooks-0.0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7b1694d5985942618f6adab0e4fe05b7", "sha256": "38f47c8e19f05718d779cbc48a1396821cc2021c4f02b2c8e26483fd3d2984fb" }, "downloads": -1, "filename": "ldap_hooks-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "7b1694d5985942618f6adab0e4fe05b7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16361, "upload_time": "2019-05-24T21:47:22", "url": "https://files.pythonhosted.org/packages/81/4a/539164e939977a3691d9533289ca2108c38399f59ebff1ba23b9a760a5e1/ldap_hooks-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ee670205721bc9fa0acc26d59b6cf3e7", "sha256": "25af801c0bca70064c1f56c8ac91a03bd9f48536391c8d4a0b620e39cc339d83" }, "downloads": -1, "filename": "ldap_hooks-0.0.3.tar.gz", "has_sig": false, "md5_digest": "ee670205721bc9fa0acc26d59b6cf3e7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17503, "upload_time": "2019-05-24T21:47:24", "url": "https://files.pythonhosted.org/packages/d9/2e/2029a8fba7b87c7dfaa4839f9e3ab0405e3b7d2992a7c94c1c2ca6a8c3fa/ldap_hooks-0.0.3.tar.gz" } ] }