finish initial documentation
This commit is contained in:
		
						commit
						60fc992191
					
				
					 28 changed files with 425 additions and 78 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -39,3 +39,4 @@ Thumbs.db | |||
| Desktop.ini | ||||
| 
 | ||||
| .ropeproject | ||||
| _build/ | ||||
|  |  | |||
							
								
								
									
										49
									
								
								README.rst
									
										
									
									
									
								
							
							
						
						
									
										49
									
								
								README.rst
									
										
									
									
									
								
							|  | @ -4,49 +4,8 @@ gvaldap | |||
| 
 | ||||
| This is the GNUViech Admin LDAP administration tool project. | ||||
| 
 | ||||
| Working Environment | ||||
| =================== | ||||
| GNUViech Admin is a suite of tools for server management used for hosting | ||||
| customer management at `Jan Dittberner IT-Consulting & -Solutions | ||||
| <http://www.gnuviech-server.de>`_. | ||||
| 
 | ||||
| You have several options in setting up your working environment.  We recommend | ||||
| using virtualenv to separate the dependencies of your project from your | ||||
| system's python environment.  If on Linux or Mac OS X, you can also use | ||||
| virtualenvwrapper to help manage multiple virtualenvs across different | ||||
| projects. | ||||
| 
 | ||||
| Virtualenv Only | ||||
| --------------- | ||||
| 
 | ||||
| First, make sure you are using virtualenv (http://www.virtualenv.org). Once | ||||
| that's installed, create your virtualenv:: | ||||
| 
 | ||||
|     $ virtualenv --distribute gvaldap | ||||
| 
 | ||||
| You will also need to ensure that the virtualenv has the project directory | ||||
| added to the path. Adding the project directory will allow `django-admin.py` to | ||||
| be able to change settings using the `--settings` flag. | ||||
| 
 | ||||
| Virtualenv with virtualenvwrapper | ||||
| ------------------------------------ | ||||
| 
 | ||||
| In Linux and Mac OSX, you can install virtualenvwrapper | ||||
| (http://virtualenvwrapper.readthedocs.org/en/latest/), which will take care of | ||||
| managing your virtual environments and adding the project path to the | ||||
| `site-directory` for you:: | ||||
| 
 | ||||
|     $ mkdir gvaldap | ||||
|     $ mkvirtualenv -a gvaldap gvaldap-dev | ||||
|     $ cd gvaldap && add2virtualenv `pwd` | ||||
| 
 | ||||
| 
 | ||||
| Installation of Dependencies | ||||
| ============================= | ||||
| 
 | ||||
| Depending on where you are installing dependencies: | ||||
| 
 | ||||
| In development:: | ||||
| 
 | ||||
|     $ pip install -r requirements/local.txt | ||||
| 
 | ||||
| For production:: | ||||
| 
 | ||||
|     $ pip install -r requirements.txt | ||||
| Read the :doc:`Installation instructions <install>` to get started locally. | ||||
|  |  | |||
							
								
								
									
										4
									
								
								docs/changelog.rst
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								docs/changelog.rst
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| Changelog | ||||
| ========= | ||||
| 
 | ||||
| * :feature:`-` intial support for creating LDAP users and groups | ||||
							
								
								
									
										97
									
								
								docs/code.rst
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								docs/code.rst
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,97 @@ | |||
| ================== | ||||
| Code documentation | ||||
| ================== | ||||
| 
 | ||||
| .. index:: Django | ||||
| 
 | ||||
| gvaldap is implemented as `Django`_ project and provides some `Celery`_ tasks. | ||||
| 
 | ||||
| .. _Django: https://www.djangoproject.com/ | ||||
| .. _Celery: http://www.celeryproject.org/ | ||||
| 
 | ||||
| 
 | ||||
| The project module :py:mod:`gvaldap` | ||||
| ==================================== | ||||
| 
 | ||||
| .. automodule:: gvaldap | ||||
| 
 | ||||
| 
 | ||||
| :py:mod:`gvaldap.celery` | ||||
| ------------------------ | ||||
| 
 | ||||
| .. automodule:: gvaldap.celery | ||||
|    :members: | ||||
| 
 | ||||
| 
 | ||||
| :py:mod:`gvaldap.urls` | ||||
| ---------------------- | ||||
| 
 | ||||
| .. automodule:: gvaldap.urls | ||||
| 
 | ||||
| 
 | ||||
| :py:mod:`gvaldap.wsgi` | ||||
| ---------------------- | ||||
| 
 | ||||
| .. automodule:: gvaldap.wsgi | ||||
|    :members: | ||||
| 
 | ||||
| 
 | ||||
| :py:mod:`gvaldap.settings` | ||||
| -------------------------- | ||||
| 
 | ||||
| .. automodule:: gvaldap.settings | ||||
| 
 | ||||
| :py:mod:`gvaldap.settings.base` | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| .. automodule:: gvaldap.settings.base | ||||
|    :members: | ||||
| 
 | ||||
| :py:mod:`gvaldap.settings.local` | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| .. automodule:: gvaldap.settings.local | ||||
| 
 | ||||
| :py:mod:`gvaldap.settings.production` | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| .. automodule:: gvaldap.settings.production | ||||
| 
 | ||||
| :py:mod:`gvaldap.settings.test` | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| .. automodule:: gvaldap.settings.test | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| :py:mod:`ldapentities` app | ||||
| ========================== | ||||
| 
 | ||||
| .. automodule:: ldapentities | ||||
| 
 | ||||
| 
 | ||||
| :py:mod:`ldapenties.admin` | ||||
| -------------------------- | ||||
| 
 | ||||
| .. automodule:: ldapentities.admin | ||||
|    :members: | ||||
| 
 | ||||
| 
 | ||||
| :py:mod:`ldapenties.models` | ||||
| --------------------------- | ||||
| 
 | ||||
| .. automodule:: ldapentities.models | ||||
|    :members: | ||||
| 
 | ||||
| 
 | ||||
| :py:mod:`osusers` app | ||||
| ===================== | ||||
| 
 | ||||
| .. automodule:: osusers | ||||
| 
 | ||||
| :py:mod:`osusers.tasks` | ||||
| ----------------------- | ||||
| 
 | ||||
| .. automodule:: osusers.tasks | ||||
|    :members: | ||||
|    :undoc-members: | ||||
							
								
								
									
										11
									
								
								docs/conf.py
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								docs/conf.py
									
										
									
									
									
								
							|  | @ -12,12 +12,13 @@ | |||
| # All configuration values have a default; values that are commented out | ||||
| # serve to show the default. | ||||
| 
 | ||||
| #import sys, os | ||||
| import sys | ||||
| import os | ||||
| 
 | ||||
| # If extensions (or modules to document with autodoc) are in another directory, | ||||
| # add these directories to sys.path here. If the directory is relative to the | ||||
| # documentation root, use os.path.abspath to make it absolute, like shown here. | ||||
| #sys.path.insert(0, os.path.abspath('.')) | ||||
| sys.path.insert(0, os.path.abspath(os.path.join('..', 'gvaldap'))) | ||||
| 
 | ||||
| # -- General configuration ----------------------------------------------------- | ||||
| 
 | ||||
|  | @ -26,11 +27,15 @@ | |||
| 
 | ||||
| # Add any Sphinx extension module names here, as strings. They can be extensions | ||||
| # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. | ||||
| extensions = [] | ||||
| extensions = ['releases', 'sphinx.ext.autodoc', 'celery.contrib.sphinx'] | ||||
| 
 | ||||
| # Add any paths that contain templates here, relative to this directory. | ||||
| templates_path = ['_templates'] | ||||
| 
 | ||||
| releases_issue_uri = 'https://dev.gnuviech-server.de/gvaldap/ticket/%s' | ||||
| 
 | ||||
| releases_release_uri = 'https://dev.gnuviech-server.de/gvaldap/milestone/%s' | ||||
| 
 | ||||
| # The suffix of source filenames. | ||||
| source_suffix = '.rst' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,10 @@ | |||
| Deploy | ||||
| ======== | ||||
| 
 | ||||
| This is where you describe how the project is deployed in production. | ||||
| The production deployment for gvaldap is performed using saltstack and consists | ||||
| of the following steps: | ||||
| 
 | ||||
| * installation of native dependencies | ||||
| * setup of a virtualenv | ||||
| * installation of gvaldap production dependencies inside the virtualenv | ||||
| * setup of celery worker under control of supervisord | ||||
|  |  | |||
|  | @ -3,6 +3,8 @@ | |||
|    You can adapt this file completely to your liking, but it should at least | ||||
|    contain the root `toctree` directive. | ||||
| 
 | ||||
| .. include:: ../README.rst | ||||
| 
 | ||||
| Welcome to gvaldap's documentation! | ||||
| ==================================== | ||||
| 
 | ||||
|  | @ -13,8 +15,8 @@ Contents: | |||
| 
 | ||||
|    install | ||||
|    deploy | ||||
|    tests | ||||
| 
 | ||||
|    code | ||||
|    changelog | ||||
| 
 | ||||
| 
 | ||||
| Indices and tables | ||||
|  |  | |||
|  | @ -1,4 +1,84 @@ | |||
| .. index:: installation | ||||
| 
 | ||||
| ======= | ||||
| Install | ||||
| ======= | ||||
| 
 | ||||
| This is where you write how to get a new laptop to run this project. | ||||
| Working Environment | ||||
| =================== | ||||
| 
 | ||||
| You have several options in setting up your working environment.  We recommend | ||||
| using virtualenv to separate the dependencies of your project from your | ||||
| system's python environment.  If on Linux or Mac OS X, you can also use | ||||
| virtualenvwrapper to help manage multiple virtualenvs across different | ||||
| projects. | ||||
| 
 | ||||
| .. index:: virtualenv | ||||
| 
 | ||||
| Virtualenv Only | ||||
| --------------- | ||||
| 
 | ||||
| First, make sure you are using `virtualenv`_. Once that's installed, create | ||||
| your virtualenv: | ||||
| 
 | ||||
| .. code-block:: sh | ||||
| 
 | ||||
|     $ virtualenv --distribute gvaldap | ||||
| 
 | ||||
| .. _virtualenv: https://virtualenv.pypa.io/en/latest/ | ||||
| 
 | ||||
| You will also need to ensure that the virtualenv has the project directory | ||||
| added to the path. Adding the project directory will allow `django-admin.py` to | ||||
| be able to change settings using the `--settings` flag. | ||||
| 
 | ||||
| .. index:: virtualenvwrapper | ||||
| 
 | ||||
| Virtualenv with virtualenvwrapper | ||||
| ------------------------------------ | ||||
| 
 | ||||
| In Linux and Mac OSX, you can install `virtualenvwrapper | ||||
| <http://virtualenvwrapper.readthedocs.org/en/latest/>`_, which will take care | ||||
| of managing your virtual environments and adding the project path to the | ||||
| `site-directory` for you: | ||||
| 
 | ||||
| .. code-block:: sh | ||||
| 
 | ||||
|     $ mkdir gvaldap | ||||
|     $ mkvirtualenv -a gvaldap gvaldap-dev | ||||
|     $ cd gvaldap && add2virtualenv `pwd` | ||||
| 
 | ||||
| 
 | ||||
| .. index:: pip, requirements, dependencies | ||||
| 
 | ||||
| Installation of Dependencies | ||||
| ============================= | ||||
| 
 | ||||
| Depending on where you are installing dependencies: | ||||
| 
 | ||||
| In development: | ||||
| 
 | ||||
| .. code-block:: sh | ||||
| 
 | ||||
|     $ pip install -r requirements/local.txt | ||||
| 
 | ||||
| For production: | ||||
| 
 | ||||
| .. code-block:: sh | ||||
| 
 | ||||
|     $ pip install -r requirements.txt | ||||
| 
 | ||||
| .. index:: celery, worker, ldap queue | ||||
| 
 | ||||
| Running the Celery worker | ||||
| ========================= | ||||
| 
 | ||||
| gvaldap uses the `Celery`_ distributed task queue system. The gvaldap logix is | ||||
| executed by a celery worker. After all dependencies are installed you can go | ||||
| into the gvaldap directory and run the celery worker with: | ||||
| 
 | ||||
| .. code-block:: sh | ||||
| 
 | ||||
|     $ cd gvaldap | ||||
|     $ celery -A gvaldap worker -Q ldap -l info | ||||
| 
 | ||||
| .. _Celery: http://www.celeryproject.org/ | ||||
|  |  | |||
|  | @ -0,0 +1,3 @@ | |||
| """ | ||||
| This is the gvaldap project module. | ||||
| """ | ||||
|  | @ -1,3 +1,9 @@ | |||
| """ | ||||
| This module defines the Celery_ app for gvaldap. | ||||
| 
 | ||||
| .. _Celery: http://www.celeryproject.org/ | ||||
| 
 | ||||
| """ | ||||
| from __future__ import absolute_import | ||||
| 
 | ||||
| import os | ||||
|  | @ -10,12 +16,8 @@ os.environ.setdefault('DJANGO_SETTINGS_MODULE', | |||
|                       'gvaldap.settings.production') | ||||
| 
 | ||||
| 
 | ||||
| #: The Celery application | ||||
| app = Celery('gvaldap') | ||||
| 
 | ||||
| app.config_from_object('django.conf:settings') | ||||
| app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) | ||||
| 
 | ||||
| 
 | ||||
| @app.task(bind=True) | ||||
| def debug_task(self): | ||||
|     print('Request: {0!r}'.format(self.request)) | ||||
|  |  | |||
|  | @ -1 +1,3 @@ | |||
| 
 | ||||
| """ | ||||
| This module contains settings for various environments. | ||||
| """ | ||||
|  |  | |||
|  | @ -1,5 +1,9 @@ | |||
| """Common settings and globals.""" | ||||
| # -*- coding: utf-8 -*- | ||||
| # pymode:lint_ignore=E501 | ||||
| """ | ||||
| Common settings and globals. | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| 
 | ||||
| from os.path import abspath, basename, dirname, join, normpath | ||||
|  | @ -12,7 +16,14 @@ from django.core.exceptions import ImproperlyConfigured | |||
| 
 | ||||
| 
 | ||||
| def get_env_setting(setting): | ||||
|     """ Get the environment setting or return exception """ | ||||
|     """ | ||||
|     Get the environment setting or return exception. | ||||
| 
 | ||||
|     :param str setting: name of an environment setting | ||||
|     :raises ImproperlyConfigured: if the environment setting is not defined | ||||
|     :return: environment setting value | ||||
|     :rtype: str | ||||
|     """ | ||||
|     try: | ||||
|         return environ[setting] | ||||
|     except KeyError: | ||||
|  |  | |||
|  | @ -1,5 +1,8 @@ | |||
| """Development settings and globals.""" | ||||
| # pymode:lint_ignore=W0401,E501 | ||||
| """ | ||||
| Development settings and globals based on :py:mod:`gvaldap.settings.base`. | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| from __future__ import absolute_import | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,8 @@ | |||
| """Production settings and globals.""" | ||||
| # pymode:lint_ignore=W0401,E501 | ||||
| """ | ||||
| Production settings and globals based on :py:mod:`gvaldap.settings.base`. | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| from __future__ import absolute_import | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,8 @@ | |||
| # pymode:lint_ignore=W0401 | ||||
| """ | ||||
| Test settings based on :py:mod:`gvaldap.settings.base`. | ||||
| 
 | ||||
| """ | ||||
| from __future__ import absolute_import | ||||
| 
 | ||||
| from .base import * | ||||
|  |  | |||
|  | @ -1,3 +1,8 @@ | |||
| """ | ||||
| This module defines the main URLConf for gvaldap. | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| from django.conf.urls import patterns, include, url | ||||
| from django.conf import settings | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,10 +26,10 @@ path.append(SITE_ROOT) | |||
| # os.environ["DJANGO_SETTINGS_MODULE"] = "jajaja.settings" | ||||
| os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gvaldap.settings.production") | ||||
| 
 | ||||
| from django.core.wsgi import get_wsgi_application | ||||
| # This application object is used by any WSGI server configured to use this | ||||
| # file. This includes Django's development server, if the WSGI_APPLICATION | ||||
| # setting points here. | ||||
| from django.core.wsgi import get_wsgi_application | ||||
| application = get_wsgi_application() | ||||
| 
 | ||||
| # Apply WSGI middleware here. | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| """ | ||||
| This app takes care of managing LDAP entities, at the moment these are: | ||||
| 
 | ||||
| * LDAP groups (:py:class:`ldapentities.models.LdapGroup`). | ||||
| * LDAP users (:py:class:`ldapentities.models.LdapUser`) | ||||
| 
 | ||||
| """ | ||||
|  | @ -1,3 +1,10 @@ | |||
| """ | ||||
| Admin classes for easy `django admin`_ based administration of LDAP entities. | ||||
| 
 | ||||
| .. _django admin: https://docs.djangoproject.com/en/dev/ref/contrib/admin/ | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| from django.contrib import admin | ||||
| 
 | ||||
| from .models import ( | ||||
|  | @ -7,12 +14,22 @@ from .models import ( | |||
| 
 | ||||
| 
 | ||||
| class LdapGroupAdmin(admin.ModelAdmin): | ||||
|     """ | ||||
|     Admin class for :py:class:`LDAP group <ldapentities.models.LdapGroup>` | ||||
|     entities. | ||||
| 
 | ||||
|     """ | ||||
|     exclude = ['dn', 'members'] | ||||
|     list_display = ['name', 'gid'] | ||||
|     search_fields = ['name'] | ||||
| 
 | ||||
| 
 | ||||
| class LdapUserAdmin(admin.ModelAdmin): | ||||
|     """ | ||||
|     Admin class for :py:class:`LDAP user <ldapentities.models.LdapUser>` | ||||
|     entities. | ||||
| 
 | ||||
|     """ | ||||
|     exclude = ['dn', 'password'] | ||||
|     list_display = ['username', 'uid'] | ||||
|     search_fields = ['username'] | ||||
|  |  | |||
|  | @ -1,3 +1,12 @@ | |||
| """ | ||||
| This module defines models for LDAP entities. | ||||
| 
 | ||||
| The models are based on :py:class:`ldapmodels.Model` from `django-ldapdb`_. | ||||
| 
 | ||||
| .. _django-ldapdb: https://github.com/jlaine/django-ldapdb#readme | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| from django.conf import settings | ||||
| from django.utils.encoding import python_2_unicode_compatible | ||||
| from ldapdb.models.fields import ( | ||||
|  | @ -13,44 +22,87 @@ from passlib.hash import ldap_salted_sha1 | |||
| @python_2_unicode_compatible | ||||
| class LdapGroup(ldapmodels.Model): | ||||
|     """ | ||||
|     Class for representing an LDAP group entity. | ||||
|     Class for representing an LDAP group entity with objectClass `posixGroup`. | ||||
| 
 | ||||
|     .. seealso:: :rfc:`2307#section-4` | ||||
| 
 | ||||
|     .. py:attribute:: base_dn | ||||
| 
 | ||||
|        a string containing the LDAP base distinguished name | ||||
| 
 | ||||
|     .. py:attribute:: members | ||||
| 
 | ||||
|        contains the list of `memberUid` attributes | ||||
| 
 | ||||
|     """ | ||||
|     # LDAP meta-data | ||||
|     base_dn = settings.GROUP_BASE_DN | ||||
|     #: list of object classes | ||||
|     object_classes = ['posixGroup'] | ||||
| 
 | ||||
|     # posixGroup attributes | ||||
|     #: group id (`gidNumber`) | ||||
|     gid = IntegerField(db_column='gidNumber', unique=True) | ||||
|     #: group name (`cn`) | ||||
|     name = CharField(db_column='cn', max_length=200, primary_key=True) | ||||
|     #: group description (`description`) | ||||
|     description = CharField(db_column='description') | ||||
|     members = ListField(db_column='memberUid', blank=True) | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         """ | ||||
|         Get a string representation of this LDAP group. | ||||
|         """ | ||||
|         return self.name | ||||
| 
 | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
| class LdapUser(ldapmodels.Model): | ||||
|     """ | ||||
|     Class for representing an LDAP user entity. | ||||
|     Class for representing an LDAP user entity with objectClasses `account` and | ||||
|     `posixAccount`. | ||||
| 
 | ||||
|     .. seealso:: :rfc:`2307#section-4`, :rfc:`4524#section-3.1` | ||||
| 
 | ||||
|     .. py:attribute:: base_dn | ||||
| 
 | ||||
|        a string containing the LDAP base distinguished name | ||||
| 
 | ||||
|     """ | ||||
|     base_dn = settings.USER_BASE_DN | ||||
|     #: list of object classes | ||||
|     object_classes = ['account', 'posixAccount'] | ||||
| 
 | ||||
|     # posixAccount | ||||
|     #: user id (`uidNumber`) | ||||
|     uid = IntegerField(db_column='uidNumber', unique=True) | ||||
|     #: group id (`gidNumber`) of the user's primary group | ||||
|     group = IntegerField(db_column='gidNumber') | ||||
|     #: GECOS field (`gecos`) | ||||
|     gecos = CharField(db_column='gecos') | ||||
|     #: home directory (`homeDirectory`) | ||||
|     home_directory = CharField(db_column='homeDirectory') | ||||
|     #: login shell (`loginShell`) | ||||
|     login_shell = CharField(db_column='loginShell', default='/bin/bash') | ||||
|     #: user name (`uid`) | ||||
|     username = CharField(db_column='uid', primary_key=True) | ||||
|     #: password (`userPassword`) in an LDAP compatible format | ||||
|     password = CharField(db_column='userPassword') | ||||
|     #: common name (`cn`) | ||||
|     common_name = CharField(db_column='cn') | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         """ | ||||
|         Get a string representation of this LDAP user. | ||||
|         """ | ||||
|         return self.username | ||||
| 
 | ||||
|     def set_password(self, password): | ||||
|         """ | ||||
|         Sets the encrypted password of the user from the given clear text | ||||
|         password. | ||||
| 
 | ||||
|         :param str password: the clear text password | ||||
| 
 | ||||
|         """ | ||||
|         self.password = ldap_salted_sha1.encrypt(password) | ||||
|  |  | |||
|  | @ -1,3 +0,0 @@ | |||
| from django.test import TestCase | ||||
| 
 | ||||
| # Create your tests here. | ||||
|  | @ -0,0 +1,3 @@ | |||
| """ | ||||
| This module contains :py:mod:`osusers.tasks`. | ||||
| """ | ||||
|  | @ -1,3 +0,0 @@ | |||
| from django.contrib import admin | ||||
| 
 | ||||
| # Register your models here. | ||||
|  | @ -0,0 +1,3 @@ | |||
| """ | ||||
| Empty models module required for Django to accept this as an app. | ||||
| """ | ||||
|  | @ -1,9 +1,17 @@ | |||
| """ | ||||
| This module defines `Celery`_ tasks to manage LDAP entities. | ||||
| 
 | ||||
| .. _Celery: http://www.celeryproject.org/ | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| from __future__ import absolute_import | ||||
| 
 | ||||
| from django.core.exceptions import ObjectDoesNotExist | ||||
| from celery import shared_task | ||||
| from celery.utils.log import get_task_logger | ||||
| from celery.exceptions import Reject | ||||
| 
 | ||||
| from ldapentities.models import ( | ||||
|     LdapGroup, | ||||
|     LdapUser, | ||||
|  | @ -15,6 +23,19 @@ _logger = get_task_logger(__name__) | |||
| 
 | ||||
| @shared_task | ||||
| def create_ldap_group(groupname, gid, descr): | ||||
|     """ | ||||
|     This task creates an :py:class:`LDAP group <ldapentities.models.LdapGroup>` | ||||
|     if it does not exist yet. | ||||
| 
 | ||||
|     If a group with the given name exists its group id and description | ||||
|     attributes are updated. | ||||
| 
 | ||||
|     :param str groupname: the group name | ||||
|     :param int gid: the group id | ||||
|     :param str descr: description text for the group | ||||
|     :return: the distinguished name of the group | ||||
|     :rtype: str | ||||
|     """ | ||||
|     try: | ||||
|         ldapgroup = LdapGroup.objects.get(name=groupname) | ||||
|         _logger.info( | ||||
|  | @ -30,6 +51,28 @@ def create_ldap_group(groupname, gid, descr): | |||
| 
 | ||||
| @shared_task | ||||
| def create_ldap_user(username, uid, gid, gecos, homedir, shell, password): | ||||
|     """ | ||||
|     This task creates an :py:class:`LDAP user <ldapentities.models.LdapUser>` | ||||
|     if it does not exist yet. | ||||
| 
 | ||||
|     The task is rejected if the primary group of the user is not defined. | ||||
| 
 | ||||
|     The user's fields are updated if the user already exists. | ||||
| 
 | ||||
|     :param str username: the user name | ||||
|     :param int uid: the user id | ||||
|     :param int gid: the user's primary group's id | ||||
|     :param str gecos: the text for the GECOS field | ||||
|     :param str homedir: the user's home directory | ||||
|     :param str shell: the user's login shell | ||||
|     :param str or None password: the clear text password, if :py:const:`None` | ||||
|         is passed the password is not touched | ||||
|     :raises celery.exceptions.Reject: if the specified primary group does not | ||||
|         exist | ||||
|     :return: the distinguished name of the user | ||||
|     :rtype: str | ||||
| 
 | ||||
|     """ | ||||
|     try: | ||||
|         ldapuser = LdapUser.objects.get(username=username) | ||||
|         _logger.info( | ||||
|  | @ -64,6 +107,19 @@ def create_ldap_user(username, uid, gid, gecos, homedir, shell, password): | |||
| 
 | ||||
| @shared_task(bind=True) | ||||
| def add_ldap_user_to_group(self, username, groupname): | ||||
|     """ | ||||
|     This task adds the specified user to the given group. | ||||
| 
 | ||||
|     This task does nothing if the user is already member of the group. | ||||
| 
 | ||||
|     :param str username: the user name | ||||
|     :param str groupname: the group name | ||||
|     :raises celery.exceptions.Retry: if the user does not exist yet, | ||||
|         :py:func:`create_ldap_user` should be called before | ||||
|     :return: True if the user has been added to the group otherwise False | ||||
|     :rtype: boolean | ||||
| 
 | ||||
|     """ | ||||
|     try: | ||||
|         ldapgroup = LdapGroup.objects.get(name=groupname) | ||||
|         ldapuser = LdapUser.objects.get(username=username) | ||||
|  | @ -80,19 +136,40 @@ def add_ldap_user_to_group(self, username, groupname): | |||
|             _logger.info('ldap user {0} is already in group {1}'.format( | ||||
|                 ldapuser.username, ldapgroup.dn) | ||||
|             ) | ||||
|         return True | ||||
|     return False | ||||
| 
 | ||||
| 
 | ||||
| @shared_task | ||||
| def remove_ldap_user_from_group(username, groupname): | ||||
|     """ | ||||
|     This task removes the given user from the given group. | ||||
| 
 | ||||
|     :param str username: the user name | ||||
|     :param str groupname: the group name | ||||
|     :return: True if the user has been removed, False otherwise | ||||
|     :rtype: boolean | ||||
| 
 | ||||
|     """ | ||||
|     ldapgroup = LdapGroup.objects.get(name=groupname) | ||||
|     ldapuser = LdapUser.objects.get(username=username) | ||||
|     if ldapuser.username in ldapgroup.members: | ||||
|     performdelete = ldapuser.username in ldapgroup.members | ||||
|     if performdelete: | ||||
|         ldapgroup.members.remove(ldapuser.username) | ||||
|     ldapgroup.save() | ||||
|     return performdelete | ||||
| 
 | ||||
| 
 | ||||
| @shared_task | ||||
| def delete_ldap_user(username): | ||||
|     """ | ||||
|     This task deletes the given user. | ||||
| 
 | ||||
|     :param str username: the user name | ||||
|     :return: True if the user has been deleted, False otherwise | ||||
|     :rtype: boolean | ||||
| 
 | ||||
|     """ | ||||
|     try: | ||||
|         ldapuser = LdapUser.objects.get(username=username) | ||||
|     except LdapUser.DoesNotExist: | ||||
|  | @ -111,10 +188,20 @@ def delete_ldap_user(username): | |||
|                 ldapgroup.members.remove(ldapuser.username) | ||||
|                 ldapgroup.save() | ||||
|         ldapuser.delete() | ||||
|         return True | ||||
|     return False | ||||
| 
 | ||||
| 
 | ||||
| @shared_task | ||||
| def delete_ldap_group_if_empty(groupname): | ||||
|     """ | ||||
|     This task deletes the given group. | ||||
| 
 | ||||
|     :param str groupname: the group name | ||||
|     :return: True if the user has been deleted, False otherwise | ||||
|     :rtype: boolean | ||||
| 
 | ||||
|     """ | ||||
|     try: | ||||
|         ldapgroup = LdapGroup.objects.get(name=groupname) | ||||
|     except LdapGroup.DoesNotExist: | ||||
|  | @ -124,7 +211,9 @@ def delete_ldap_group_if_empty(groupname): | |||
|     else: | ||||
|         if len(ldapgroup.members) == 0: | ||||
|             ldapgroup.delete() | ||||
|             return True | ||||
|         else: | ||||
|             _logger.info('ldap group {0} still has {1} members'.format( | ||||
|                 ldapgroup.dn, len(ldapgroup.members)) | ||||
|             ) | ||||
|     return False | ||||
|  |  | |||
|  | @ -1,3 +0,0 @@ | |||
| from django.test import TestCase | ||||
| 
 | ||||
| # Create your tests here. | ||||
|  | @ -7,7 +7,4 @@ logutils==0.3.3 | |||
| South==0.8.4 | ||||
| celery==3.1.11 | ||||
| passlib==1.6.2 | ||||
| billiard==3.3.0.17 | ||||
| kombu==3.0.16 | ||||
| pytz==2014.3 | ||||
| pyaml==14.05.7 | ||||
|  |  | |||
|  | @ -4,3 +4,4 @@ coverage==3.7.1 | |||
| django-debug-toolbar==1.2.1 | ||||
| Sphinx==1.2.2 | ||||
| sqlparse==0.1.11 | ||||
| releases==0.6.1 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue