diff --git a/settings.py b/settings.py index 45ddabf..d67feea 100644 --- a/settings.py +++ b/settings.py @@ -84,3 +84,14 @@ INSTALLED_APPS = ( ) AUTH_PROFILE_MODULE = 'sso.UserProfile' + +### Jabber Service Settings + +# Vhost to add users to +JABBER_SERVER = 'dredd.it' + +# Group to add authed people to +JABBER_GROUP = 'dreddit' + +# Use sudo? +JABBER_SUDO = True diff --git a/sso/admin.py b/sso/admin.py new file mode 100644 index 0000000..bd62fe5 --- /dev/null +++ b/sso/admin.py @@ -0,0 +1,7 @@ +""" +Admin interface models. Automatically detected by admin.autodiscover(). +""" +from django.contrib import admin +from sso.models import * + +admin.site.register(sso.models.Service) diff --git a/sso/models.py b/sso/models.py index 37046d7..a29e66c 100644 --- a/sso/models.py +++ b/sso/models.py @@ -1,14 +1,48 @@ from django.db import models +from django.db.models import signals from django.contrib.auth.models import User +from sso.service import get_api + class Service(models.Model): url = models.CharField(max_length=200) active = models.BooleanField() api = models.CharField(max_length=200) class ServiceAccount(models.Model): - user = models.ForeignKey(User) - service = models.ForeignKey(Service) - username = models.CharField(max_length=200) + user = models.ForeignKey(User,blank=False) + service = models.ForeignKey(Service,blank=False) + username = models.CharField(max_length=200,blank=False) active = models.BooleanField() + def save(self): + """ Override default save to setup accounts as needed """ + + if not self.service: + raise DoesNotExist('No Service set on this account!') + + if not self.user: + raise DoesNotExist('No User set on this account!') + + if not self.username: + self.username = self.user.name + + api = get_api(self.service.api) + + if self.active: + if not api.check_user(self.username): + api.add_user(self.username, self.password) + else: + if api.check_user(self.username): + api.del_user(self.username) + + # All went OK, save to the DB + return models.Model.save(self) + + @staticmethod + def pre_delete_listener( **kwargs ): + api = get_api(kwargs['instance'].service.api) + if api.check_user(kwargs['instance'].username): + api.del_user(kwargs['instance'].username) + +signals.pre_delete.connect(ServiceAccount.pre_delete_listener, sender=ServiceAccount) diff --git a/sso/services/__init__.py b/sso/services/__init__.py index 885718d..d7c4fe7 100644 --- a/sso/services/__init__.py +++ b/sso/services/__init__.py @@ -1,4 +1,16 @@ +def get_api(api): + try: + mod = __import__(self.service.api) + except ImportError: + raise DoesNotExist('Error creating service') + + for i in self.service.api.spit(".")[1:]: + mod = getattr(mod, i) + + return getattr(mod, mod.ServiceClass)() + + class BaseService(): """ Base Service class, all service classes should inherit from this diff --git a/sso/services/jabber/__init__.py b/sso/services/jabber/__init__.py new file mode 100644 index 0000000..8e6f421 --- /dev/null +++ b/sso/services/jabber/__init__.py @@ -0,0 +1,37 @@ +from sso.services import BaseService +from sso.services.jabber.ejabberdctl import eJabberdCtl +import settings + +class JabberService(BaseService): + + def __init__(self): + self.ejctl = eJabberdCtl(sudo=settings.JABBER_SUDO) + + def add_user(username, password): + """ Add user to service """ + return self.ejctl.register(username, settings.JABBER_SERVER, password) + + def set_corp(self, username): + """ User is in corp, enable extra privs """ + return self.ejctl.srg_user_add(username, settings.JABBER_SERVER, settings.JABBER_GROUP) + + def delete_user(self, username): + """ Delete a user """ + return self.ejctl.unregister(username, settings.JABBER_SERVER) + + def disable_user(self, username): + """ Disable a user """ + return self.ejctl.ban_user(settings.JABBER_SERVER, username) + + def enable_user(self, username): + """ Enable a user """ + + + def check_user(self, username): + """ Check if the username exists """ + if username not in self.ejctl.get_users(settings.JABBER_SERVER): + return False + else: + return True + +ServiceClass = 'JabberService' diff --git a/sso/services/ejabberdctl.py b/sso/services/jabber/ejabberdctl.py similarity index 94% rename from sso/services/ejabberdctl.py rename to sso/services/jabber/ejabberdctl.py index dc2964f..f4f5469 100644 --- a/sso/services/ejabberdctl.py +++ b/sso/services/jabber/ejabberdctl.py @@ -12,21 +12,27 @@ class CommandError(): class eJabberdCtl(): """ Python abstraction of ejabberdctl """ - def __init__(self, ejctl='/usr/sbin/ejabberdctl'): - self.ejctl = ejctl + def __init__(self, sudo=False, ejctl='/usr/sbin/ejabberdctl'): + if sudo: + self.ejctl = ['sudo',ejctl] + else: + self.ejctl = [ejctl] def _execute(self, commandline): """ Execute a ejabberd command """ - args = [self.ejctl] + args = [] + args.extend(self.ejctl) args.extend(shlex.split(commandline)) + print args + try: proc = subprocess.Popen(args, stdout=subprocess.PIPE) proc.wait() out = proc.communicate() ret = proc.returncode - print "%d: %s" % (ret, out) + #print "%d: %s" % (ret, out) except OSError, e: raise CommandError('Error encountered during execution: %s' % e) if ret > 0: @@ -184,11 +190,10 @@ class eJabberdCtl(): """ Gets a list of users for a specific vhost """ cmd = "vhost %s registered-users" % server - try: out = self._execute(cmd) except CommandError, e: - return 0 + return [] else: return out[:-1].split('\n') @@ -218,7 +223,7 @@ class eJabberdCtl(): return True if __name__ == '__main__': - b = eJabberdCtl() + b = eJabberdCtl(sudo=True) print b.register('test88','dredd.it','bleh') print b.is_online('matalok', 'dredd.it') diff --git a/test.py b/test.py new file mode 100644 index 0000000..19ede48 --- /dev/null +++ b/test.py @@ -0,0 +1,9 @@ +import os + +os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' + +from sso.services.jabber import JabberService + +b = JabberService() + +print b.check_user('matalok')