1
0
Fork 0

* some pylint fixes (addresses #24)

* add pydoc in client and domain backend classes
 * add support for buildutils in setup.py


git-svn-id: file:///home/www/usr01/svn/gnuviechadmin/trunk@262 a67ec6bc-e5d5-0310-a910-815c51eb3124
This commit is contained in:
Jan Dittberner 2008-06-07 21:25:35 +00:00
parent 4ee62d5b2e
commit daf9517a83
13 changed files with 147 additions and 69 deletions

View File

@ -18,16 +18,16 @@
# USA. # USA.
# #
# Version: $Id$ # Version: $Id$
"""This module defines the BackendEntity base class."""
import os import os
import logging import logging
import tempfile import tempfile
from settings import config from gnuviechadmin.exceptions import MissingFieldsError
from gnuviechadmin.exceptions import * from gnuviechadmin.backend.settings import config
from gnuviechadmin.util import gpgmail from gnuviechadmin.util import gpgmail
from subprocess import * from subprocess import Popen, PIPE
import sqlalchemy
from sqlalchemy.orm import object_mapper from sqlalchemy.orm import object_mapper
@ -52,17 +52,17 @@ class BackendEntity(object):
suwrapper = config.get('common', 'suwrapper') suwrapper = config.get('common', 'suwrapper')
toexec = "%s %s" % (suwrapper, cmdline) toexec = "%s %s" % (suwrapper, cmdline)
if pipedata: if pipedata:
p = Popen(toexec, shell = True, stdin=PIPE) pipeproc = Popen(toexec, shell = True, stdin=PIPE)
pipe = p.stdin pipe = pipeproc.stdin
print >>pipe, pipedata print >> pipe, pipedata
pipe.close() pipe.close()
sts = os.waitpid(p.pid, 0) sts = os.waitpid(pipeproc.pid, 0)
if self.verbose: if self.verbose:
print "%s|%s: %d" % (pipedata, toexec, sts[1]) print "%s|%s: %d" % (pipedata, toexec, sts[1])
self.logger.info("%s|%s: %d", pipedata, toexec, sts[1]) self.logger.info("%s|%s: %d", pipedata, toexec, sts[1])
else: else:
p = Popen(toexec, shell = True) pipeproc = Popen(toexec, shell = True)
sts = os.waitpid(p.pid, 0) sts = os.waitpid(pipeproc.pid, 0)
if self.verbose: if self.verbose:
print "%s: %s" % (toexec, sts[1]) print "%s: %s" % (toexec, sts[1])
self.logger.info("%s: %s", toexec, sts[1]) self.logger.info("%s: %s", toexec, sts[1])
@ -77,11 +77,11 @@ class BackendEntity(object):
for cmdline in cmdlines: for cmdline in cmdlines:
toexec = "%s %s" % (suwrapper, cmdline) toexec = "%s %s" % (suwrapper, cmdline)
if predecessor is None: if predecessor is None:
p = Popen(toexec, shell = True, stdout = PIPE) pipeproc = Popen(toexec, shell = True, stdout = PIPE)
else: else:
p = Popen(toexec, shell = True, stdin = predecessor.stdout, pipeproc = Popen(toexec, shell = True,
stdout = PIPE) stdin = predecessor.stdout, stdout = PIPE)
predecessor = p predecessor = pipeproc
output = predecessor.communicate()[0] output = predecessor.communicate()[0]
return predecessor.wait() return predecessor.wait()

View File

@ -18,17 +18,18 @@
# USA. # USA.
# #
# Version: $Id$ # Version: $Id$
"""This module defines the BackendEntityHandler class."""
import sqlalchemy
import logging import logging
from sqlalchemy.orm import create_session from sqlalchemy.orm import create_session
from gnuviechadmin.exceptions import *
from BackendEntity import *
class BackendEntityHandler(object): class BackendEntityHandler(object):
"""This class is a handler for BackendEntity instances."""
def __init__(self, entityclass, toclass, verbose = False): def __init__(self, entityclass, toclass, verbose = False):
"""Initialize the handler with a specific entity class,
transfer object class and verbosity flag."""
self.logger = logging.getLogger("%s.%s" % ( self.logger = logging.getLogger("%s.%s" % (
self.__class__.__module__, self.__class__.__name__)) self.__class__.__module__, self.__class__.__name__))
self.entityclass = entityclass self.entityclass = entityclass
@ -74,17 +75,17 @@ class BackendEntityHandler(object):
sess = create_session() sess = create_session()
transaction = sess.create_transaction() transaction = sess.create_transaction()
try: try:
to = sess.query(self.toclass).get(pkvalue) tobj = sess.query(self.toclass).get(pkvalue)
if to: if tobj:
entity = self.entityclass(to, self.verbose) entity = self.entityclass(tobj, self.verbose)
self.logger.info("delete %s", str(entity)) self.logger.info("delete %s", str(entity))
if self.verbose: if self.verbose:
print "delete %s" % (str(entity)) print "delete %s" % (str(entity))
entity.delete_hook(sess) entity.delete_hook(sess)
sess.delete(to) sess.delete(tobj)
sess.flush() sess.flush()
transaction.commit() transaction.commit()
except Exception, e: except Exception:
transaction.rollback() transaction.rollback()
self.logger.exception("Exception in delete.") self.logger.exception("Exception in delete.")
raise raise

View File

@ -18,18 +18,21 @@
# USA. # USA.
# #
# Version: $Id$ # Version: $Id$
"""This module defines the ClientEntity class."""
from gnuviechadmin.exceptions import * from gnuviechadmin.backend.settings import config, get_template, \
from settings import config get_template_string
from BackendTo import * from gnuviechadmin.exceptions import CannotDeleteError
from BackendEntity import * from gnuviechadmin.backend.BackendTo import Client
from BackendEntityHandler import * from gnuviechadmin.backend.BackendEntity import BackendEntity
from gnuviechadmin.backend.BackendEntityHandler import BackendEntityHandler
class ClientEntity(BackendEntity): class ClientEntity(BackendEntity):
"""Entity class for clients.""" """Entity class for clients."""
def __init__(self, delegate, verbose = False, **kwargs): def __init__(self, delegate, verbose = False, **kwargs):
"""Initializes the client entity instance."""
BackendEntity.__init__(self, delegate, verbose) BackendEntity.__init__(self, delegate, verbose)
for (key, value) in kwargs.items(): for (key, value) in kwargs.items():
self.__setattr__(key, value) self.__setattr__(key, value)
@ -38,6 +41,7 @@ class ClientEntity(BackendEntity):
self.validate() self.validate()
def _client_mail(self): def _client_mail(self):
"""Mails a summary about the creation of the client."""
text = get_template(config.get('common', 'mailtemplates'), text = get_template(config.get('common', 'mailtemplates'),
config.get('client', 'create.mail')).substitute({ config.get('client', 'create.mail')).substitute({
'firstname': self.delegateto.firstname, 'firstname': self.delegateto.firstname,

View File

@ -18,27 +18,35 @@
# USA. # USA.
# #
# Version: $Id$ # Version: $Id$
"""This module defines the code for handling domains."""
import datetime import datetime
import os import os
from gnuviechadmin.exceptions import * from gnuviechadmin.exceptions import ValidationFailedError
from settings import * from gnuviechadmin.backend.settings import config, get_template, \
from BackendTo import Record, Domain get_template_dir, get_template_string
from BackendEntity import BackendEntity from gnuviechadmin.backend.BackendTo import Record, Domain
from BackendEntityHandler import BackendEntityHandler from gnuviechadmin.backend.BackendEntity import BackendEntity
from gnuviechadmin.backend.BackendEntityHandler import BackendEntityHandler
class DomainEntity(BackendEntity): class DomainEntity(BackendEntity):
"""Entity class for DNS domains.""" """Entity class for DNS domains."""
# the valid domain types
_valid_domain_types = ("MASTER", "SLAVE") _valid_domain_types = ("MASTER", "SLAVE")
def __init__(self, delegate, verbose = False, **kwargs): def __init__(self, delegate, verbose = False, **kwargs):
"""Initializes the DomainEntity instance.
`delegate` is the corresponding database object.
If `verbose` is `True` verbose logging is turned on.
"""
BackendEntity.__init__(self, delegate, verbose) BackendEntity.__init__(self, delegate, verbose)
self.ns1 = None self.ns1 = None
self.ns2 = None self.ns2 = None
self.mx = None self.mxrr = None
self.ipaddr = None self.ipaddr = None
for (key, value) in kwargs.items(): for (key, value) in kwargs.items():
self.__setattr__(key, value) self.__setattr__(key, value)
@ -48,17 +56,20 @@ class DomainEntity(BackendEntity):
self.ns1 = config.get('domain', 'defaultns1') self.ns1 = config.get('domain', 'defaultns1')
if not self.ns2: if not self.ns2:
self.ns2 = config.get('domain', 'defaultns2') self.ns2 = config.get('domain', 'defaultns2')
if not self.mx: if not self.mxrr:
self.mx = config.get('domain', 'defaultmx') self.mxrr = config.get('domain', 'defaultmx')
if not self.ipaddr: if not self.ipaddr:
self.ipaddr = config.get('domain', 'defaultip') self.ipaddr = config.get('domain', 'defaultip')
self.delegateto.type = self.delegateto.type.upper() self.delegateto.type = self.delegateto.type.upper()
self.validate() self.validate()
def getdefaultdomaintype(self): def getdefaultdomaintype(self):
"""Returns the default domain type."""
return self._valid_domain_types[0] return self._valid_domain_types[0]
def validate(self): def validate(self):
"""Validates the consistency if the entity instance and
dependent entities."""
BackendEntity.validate(self) BackendEntity.validate(self)
if not self.delegateto.type in self._valid_domain_types: if not self.delegateto.type in self._valid_domain_types:
raise ValidationFailedError( raise ValidationFailedError(
@ -70,11 +81,12 @@ class DomainEntity(BackendEntity):
if not self.ns1 or not self.ns2: if not self.ns1 or not self.ns2:
raise ValidationFailedError( raise ValidationFailedError(
self, "two nameservers must be specified.") self, "two nameservers must be specified.")
if not self.mx: if not self.mxrr:
raise ValidationFailedError( raise ValidationFailedError(
self, "a primary mx host must be specified.") self, "a primary mx host must be specified.")
def _getnewserial(self, oldserial = None): def _getnewserial(self, oldserial = None):
"""Gets a new zone serial number for the DNS domain entity."""
current = datetime.datetime.now() current = datetime.datetime.now()
datepart = "%04d%02d%02d" % \ datepart = "%04d%02d%02d" % \
(current.year, current.month, current.day) (current.year, current.month, current.day)
@ -87,6 +99,7 @@ class DomainEntity(BackendEntity):
return retval return retval
def _getnewsoa(self): def _getnewsoa(self):
"""Gets a new SOA record for the DNS domain entity."""
return '%s %s %d %d %d %d %d' % \ return '%s %s %d %d %d %d %d' % \
(self.ns1, (self.ns1,
config.get('domain', 'defaulthostmaster'), config.get('domain', 'defaulthostmaster'),
@ -97,6 +110,7 @@ class DomainEntity(BackendEntity):
config.getint('domain', 'defaultminimumttl')) config.getint('domain', 'defaultminimumttl'))
def update_serial(self, session): def update_serial(self, session):
"""Updates the serial of the domain."""
query = session.query(Record) query = session.query(Record)
soarecord = query.get_by(Record.c.type == 'SOA', soarecord = query.get_by(Record.c.type == 'SOA',
Record.c.domainid == self.delegateto.domainid) Record.c.domainid == self.delegateto.domainid)
@ -107,19 +121,24 @@ class DomainEntity(BackendEntity):
session.flush() session.flush()
def _get_vhost_dir(self): def _get_vhost_dir(self):
"""Gets the directory name for the Apache VirtualHost of the
domain."""
return os.path.join(self.delegateto.sysuser.home, return os.path.join(self.delegateto.sysuser.home,
self.delegateto.name, self.delegateto.name,
config.get('domain', 'htdir')) config.get('domain', 'htdir'))
def _get_log_dir(self): def _get_log_dir(self):
"""Gets the Apache log file directory for the domain."""
return os.path.join(config.get('domain', 'logpath'), return os.path.join(config.get('domain', 'logpath'),
self.delegateto.name) self.delegateto.name)
def _get_stats_dir(self): def _get_stats_dir(self):
"""Gets the statistics dir for the domain."""
return os.path.join(config.get('domain', 'statspath'), return os.path.join(config.get('domain', 'statspath'),
self.delegateto.name) self.delegateto.name)
def _create_vhost_dir(self): def _create_vhost_dir(self):
"""Creates the Apache VirtualHost directory for the domain."""
vhostdir = self._get_vhost_dir() vhostdir = self._get_vhost_dir()
self.logger.debug("creating virtual host dir %s" % (vhostdir)) self.logger.debug("creating virtual host dir %s" % (vhostdir))
cmd = 'mkdir -p "%s"' % (vhostdir) cmd = 'mkdir -p "%s"' % (vhostdir)
@ -140,10 +159,13 @@ class DomainEntity(BackendEntity):
self.sucommand(cmd) self.sucommand(cmd)
def _create_log_dir(self): def _create_log_dir(self):
"""Creates the Apache log file directory for the domain."""
cmd = 'mkdir -p "%s"' % (self._get_log_dir()) cmd = 'mkdir -p "%s"' % (self._get_log_dir())
self.sucommand(cmd) self.sucommand(cmd)
def _get_auth_userfile(self): def _get_auth_userfile(self):
"""Gets the file name of the password file for statistic
logins for the domain."""
authdir = config.get('domain', 'authdir') authdir = config.get('domain', 'authdir')
if not os.path.isdir(authdir): if not os.path.isdir(authdir):
cmd = 'mkdir -p "%s"' % (authdir) cmd = 'mkdir -p "%s"' % (authdir)
@ -171,6 +193,8 @@ class DomainEntity(BackendEntity):
'.htaccess'), template) '.htaccess'), template)
def _create_stats_conf(self): def _create_stats_conf(self):
"""Creates the modlogan statistics configuration for the
domain."""
modlogandir = os.path.join(config.get('domain', modlogandir = os.path.join(config.get('domain',
'modlogandir'), 'modlogandir'),
self.delegateto.sysuser.username) self.delegateto.sysuser.username)
@ -188,6 +212,7 @@ class DomainEntity(BackendEntity):
template) template)
def _create_apache_conf(self): def _create_apache_conf(self):
"""Creates the Apache configuration file for the domain."""
template = get_template(config.get('domain', 'conftemplates'), template = get_template(config.get('domain', 'conftemplates'),
config.get('domain', 'apachetemplate')) config.get('domain', 'apachetemplate'))
template = template.substitute({ template = template.substitute({
@ -200,6 +225,7 @@ class DomainEntity(BackendEntity):
self.delegateto.name), template) self.delegateto.name), template)
def _mail_domain(self): def _mail_domain(self):
"""Mail a summary of the domain data."""
template = get_template(config.get('common', 'mailtemplates'), template = get_template(config.get('common', 'mailtemplates'),
config.get('domain', 'create.mail')) config.get('domain', 'create.mail'))
text = template.substitute({ text = template.substitute({
@ -213,6 +239,11 @@ class DomainEntity(BackendEntity):
self.send_mail(subject, text) self.send_mail(subject, text)
def create_hook(self, session): def create_hook(self, session):
"""Hook for the creation of the domain.
This method is called by
`gnuviechadmin.backend.BackendEntityHandler.create()`.
"""
self.delegateto.records.append(Record( self.delegateto.records.append(Record(
name = self.delegateto.name, type = 'SOA', name = self.delegateto.name, type = 'SOA',
content = self._getnewsoa(), content = self._getnewsoa(),
@ -224,7 +255,7 @@ class DomainEntity(BackendEntity):
name = self.delegateto.name, type = 'NS', content = self.ns2, name = self.delegateto.name, type = 'NS', content = self.ns2,
ttl = config.getint('domain', 'defaultttl'))) ttl = config.getint('domain', 'defaultttl')))
self.delegateto.records.append(Record( self.delegateto.records.append(Record(
name = self.delegateto.name, type = 'MX', content = self.mx, name = self.delegateto.name, type = 'MX', content = self.mxrr,
ttl = config.getint('domain', 'defaultttl'), ttl = config.getint('domain', 'defaultttl'),
prio = config.getint('domain', 'defaultmxprio'))) prio = config.getint('domain', 'defaultmxprio')))
self.delegateto.records.append(Record( self.delegateto.records.append(Record(
@ -244,6 +275,7 @@ class DomainEntity(BackendEntity):
self._mail_domain() self._mail_domain()
def _delete_apache_conf(self): def _delete_apache_conf(self):
"""Deletes the Apache configuration file for the domain."""
cmd = 'a2dissite %s' % (self.delegateto.name) cmd = 'a2dissite %s' % (self.delegateto.name)
self.sucommand(cmd) self.sucommand(cmd)
cmd = 'rm "%s"' % (os.path.join(config.get('domain', 'sitesdir'), cmd = 'rm "%s"' % (os.path.join(config.get('domain', 'sitesdir'),
@ -251,12 +283,15 @@ class DomainEntity(BackendEntity):
self.sucommand(cmd) self.sucommand(cmd)
def _delete_stats_conf(self): def _delete_stats_conf(self):
"""Deletes the modlogan stastics configuration for the
domain."""
cmd = 'rm "%s"' % (os.path.join(config.get('domain', 'modlogandir'), cmd = 'rm "%s"' % (os.path.join(config.get('domain', 'modlogandir'),
self.delegateto.sysuser.username, self.delegateto.sysuser.username,
self.delegateto.name + '.conf')) self.delegateto.name + '.conf'))
self.sucommand(cmd) self.sucommand(cmd)
def _archive_stats_dir(self): def _archive_stats_dir(self):
"""Archives the statistics directory for the domain."""
archive = os.path.join(self.delegateto.sysuser.home, archive = os.path.join(self.delegateto.sysuser.home,
'%(domain)s-stats.tar.gz' % { '%(domain)s-stats.tar.gz' % {
'domain': self.delegateto.name}) 'domain': self.delegateto.name})
@ -276,6 +311,7 @@ class DomainEntity(BackendEntity):
self.sucommand(cmd) self.sucommand(cmd)
def _archive_log_dir(self): def _archive_log_dir(self):
"""Archives the Apache log file directory for the domain."""
archive = os.path.join(self.delegateto.sysuser.home, archive = os.path.join(self.delegateto.sysuser.home,
'%(domain)s-logs.tar.gz' % { '%(domain)s-logs.tar.gz' % {
'domain': self.delegateto.name}) 'domain': self.delegateto.name})
@ -295,6 +331,7 @@ class DomainEntity(BackendEntity):
self.sucommand(cmd) self.sucommand(cmd)
def _archive_vhost_dir(self): def _archive_vhost_dir(self):
"""Archives the Apache VirtualHost directory for the domain."""
archive = os.path.join(self.delegateto.sysuser.home, archive = os.path.join(self.delegateto.sysuser.home,
'%(domain)s-vhost.tar.gz' % { '%(domain)s-vhost.tar.gz' % {
'domain': self.delegateto.name}) 'domain': self.delegateto.name})
@ -315,6 +352,10 @@ class DomainEntity(BackendEntity):
self.sucommand(cmd) self.sucommand(cmd)
def delete_hook(self, session): def delete_hook(self, session):
"""Deletes domain related files and directories.
This method is called by `BackendEntityHandler.delete()`.
"""
self._delete_apache_conf() self._delete_apache_conf()
self._delete_stats_conf() self._delete_stats_conf()
self._archive_stats_dir() self._archive_stats_dir()
@ -326,4 +367,5 @@ class DomainHandler(BackendEntityHandler):
"""BackendEntityHandler for Domain entities.""" """BackendEntityHandler for Domain entities."""
def __init__(self, verbose = False): def __init__(self, verbose = False):
"""Initialize the DomainHandler."""
BackendEntityHandler.__init__(self, DomainEntity, Domain, verbose) BackendEntityHandler.__init__(self, DomainEntity, Domain, verbose)

View File

@ -27,8 +27,7 @@ templates."""
import ConfigParser import ConfigParser
import os import os
import string from string import Template
import logging.config
# global settings which must not be user configurable # global settings which must not be user configurable
required_version = 3 required_version = 3
@ -54,9 +53,9 @@ def get_template(dirname, filename):
templatefile = file(os.path.join(get_template_dir(dirname), templatefile = file(os.path.join(get_template_dir(dirname),
filename)) filename))
templatedata = templatefile.read() templatedata = templatefile.read()
return string.Template(templatedata.decode('utf_8')) return Template(templatedata.decode('utf_8'))
def get_template_string(templatestring): def get_template_string(templatestring):
"""Returns a template object for the given template string.""" """Returns a template object for the given template string."""
return string.Template(templatestring) return Template(templatestring)

View File

@ -18,12 +18,17 @@
# USA. # USA.
# #
# Version: $Id$ # Version: $Id$
import CliCommand """This module provides the command line interface code for system
user management."""
from gnuviechadmin.cli.CliCommand import CliCommand
import sys import sys
class SysuserCli(CliCommand.CliCommand): class SysuserCli(CliCommand):
"""Command line interface command for system user managament.""" """Command line interface command for system user management.
This class implements `gnuviechadmin.cli.CliCommand.CliCommand`.
"""
name = "sysuser" name = "sysuser"
description = "manage system users" description = "manage system users"
@ -47,6 +52,10 @@ class SysuserCli(CliCommand.CliCommand):
"the system user id", True)])} "the system user id", True)])}
def _execute(self, subcommand): def _execute(self, subcommand):
"""Executes `subcommand`.
This method implements `CliCommand._execute()`.
"""
self.logger.debug("execute %s with data %s", subcommand, self.logger.debug("execute %s with data %s", subcommand,
str(self._data)) str(self._data))
from gnuviechadmin.backend import sysuser from gnuviechadmin.backend import sysuser
@ -70,4 +79,5 @@ class SysuserCli(CliCommand.CliCommand):
self._data["sysuserid"]) self._data["sysuserid"])
def __init__(self, argv): def __init__(self, argv):
"""Constructor for the sysuser command."""
CliCommand.CliCommand.__init__(self, argv) CliCommand.CliCommand.__init__(self, argv)

View File

@ -32,6 +32,7 @@ class MissingFieldsError(GnuviechadminError):
class is missing.""" class is missing."""
def __init__(self, missingfields): def __init__(self, missingfields):
GnuviechadminError.__init__(self)
self.missing = missingfields self.missing = missingfields
def __str__(self): def __str__(self):
@ -43,6 +44,7 @@ class CreationFailedError(GnuviechadminError):
be created.""" be created."""
def __init__(self, classname, cause = None): def __init__(self, classname, cause = None):
GnuviechadminError.__init__(self)
self.classname = classname self.classname = classname
self.cause = cause self.cause = cause
@ -58,6 +60,7 @@ class DeleteFailedError(GnuviechadminError):
be deleted.""" be deleted."""
def __init__(self, classname, cause = None): def __init__(self, classname, cause = None):
GnuviechadminError.__init__(self)
self.classname = classname self.classname = classname
self.cause = cause self.cause = cause
@ -73,6 +76,7 @@ class ValidationFailedError(GnuviechadminError):
object failed.""" object failed."""
def __init__(self, instance, cause = None): def __init__(self, instance, cause = None):
GnuviechadminError.__init__(self)
self.instance = instance self.instance = instance
self.cause = cause self.cause = cause
@ -88,6 +92,7 @@ class CannotDeleteError(GnuviechadminError):
because of some unmatched precondition.""" because of some unmatched precondition."""
def __init__(self, instance, cause = None): def __init__(self, instance, cause = None):
GnuviechadminError.__init__(self)
self.instance = instance self.instance = instance
self.cause = cause self.cause = cause

View File

@ -28,7 +28,7 @@ import grp
class PasswdUser(object): class PasswdUser(object):
"""This class represents users in the user database.""" """This class represents users in the user database."""
def __init__(self, username, pw, uid, gid, gecos, home, shell): def __init__(self, username, passw, uid, gid, gecos, home, shell):
"""Create a new PasswdUser.""" """Create a new PasswdUser."""
self.username = username self.username = username
self.uid = int(uid) self.uid = int(uid)
@ -51,7 +51,7 @@ class PasswdUser(object):
class PasswdGroup(object): class PasswdGroup(object):
"""This class represents lines in the groups database.""" """This class represents lines in the groups database."""
def __init__(self, groupname, pw, gid, members): def __init__(self, groupname, passwd, gid, members):
"""Create a new PasswdGroup.""" """Create a new PasswdGroup."""
self.groupname = groupname self.groupname = groupname
self.gid = int(gid) self.gid = int(gid)
@ -109,7 +109,7 @@ def get_next_uid(lowerboundary = 10000, upperboundary = 65536):
""" """
for uid in range(lowerboundary, upperboundary): for uid in range(lowerboundary, upperboundary):
try: try:
user = pwd.getpwuid(uid) pwd.getpwuid(uid)
except KeyError: except KeyError:
return uid return uid
raise Exception("no free uid found in range %d to %d", raise Exception("no free uid found in range %d to %d",

View File

@ -25,14 +25,14 @@ import crack
import random import random
import logging import logging
log = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
_pwchars = [] _PWCHARS = []
for _pair in (('0', '9'), ('A', 'Z'), ('a', 'z')): for _pair in (('0', '9'), ('A', 'Z'), ('a', 'z')):
_pwchars.extend(range(ord(_pair[0]), ord(_pair[1]))) _PWCHARS.extend(range(ord(_pair[0]), ord(_pair[1])))
_saltchars = [_char for _char in _pwchars] _SALTCHARS = [_char for _char in _PWCHARS]
for _char in "-+/*_@": for _char in "-+/*_@":
_pwchars.append(ord(_char)) _PWCHARS.append(ord(_char))
def generatepassword(minlength = 8, maxlength = 12): def generatepassword(minlength = 8, maxlength = 12):
@ -41,12 +41,11 @@ def generatepassword(minlength = 8, maxlength = 12):
The generated password has a length between minlength and maxlength. The generated password has a length between minlength and maxlength.
Keyword arguments: Keyword arguments:
minlength -- minimum length of the generated password `minlength` -- minimum length of the generated password
maxlength -- the maximum length of the generated password `maxlength` -- the maximum length of the generated password
""" """
return "".join([chr(letter) for letter in \ return "".join([chr(letter) for letter in \
random.sample(_pwchars, random.sample(_PWCHARS,
random.randint(minlength, maxlength))]) random.randint(minlength, maxlength))])
@ -57,12 +56,12 @@ def checkpassword(password):
returned. returned.
Arguments: Arguments:
password -- the password to check `password` -- the password to check
""" """
try: try:
return crack.VeryFascistCheck(password) return crack.VeryFascistCheck(password)
except ValueError, ve: except ValueError, ve:
log.info("Weak password: %s", ve) LOG.info("Weak password: %s", ve)
return None return None
@ -72,10 +71,10 @@ def md5_crypt_password(password):
A password hashed with MD5 and a random salt value is returned. A password hashed with MD5 and a random salt value is returned.
Arguments: Arguments:
password -- the password to hash `password` -- the password to hash
""" """
salt = "".join([chr(letter) for letter in \ salt = "".join([chr(letter) for letter in \
random.sample(_saltchars, 8)]) random.sample(_SALTCHARS, 8)])
return crypt.crypt(password, '$1$' + salt) return crypt.crypt(password, '$1$' + salt)
@ -83,7 +82,7 @@ def get_pw_tuple(password = None):
"""Gets a valid (password, hashvalue) tuple. """Gets a valid (password, hashvalue) tuple.
The tuple consists of a password and a md5 hash of the same The tuple consists of a password and a md5 hash of the same
password. If a password is given it is checked and if it is too password. If a `password` is given it is checked and if it is too
weak replaced by a generated one. weak replaced by a generated one.
""" """
@ -92,8 +91,8 @@ def get_pw_tuple(password = None):
return (password, md5_crypt_password(password)) return (password, md5_crypt_password(password))
def validate_password(hash, password): def validate_password(hashvalue, password):
"""Validates whether the given clear text password matches the """Validates whether the given clear text `password` matches the
given hash value. given `hashvalue`.
""" """
return hash == crypt.crypt(password, hash) return hashvalue == crypt.crypt(password, hashvalue)

View File

@ -24,7 +24,7 @@
creation.""" creation."""
if __name__ == '__main__': if __name__ == '__main__':
from passwordutils import get_pw_tuple from gnuviechadmin.util.passwordutils import get_pw_tuple
import sys import sys
for line in sys.stdin.readlines(): for line in sys.stdin.readlines():

View File

@ -31,11 +31,11 @@ log = logging.getLogger(__name__)
class UserProvider(Users): class UserProvider(Users):
"""A base class for user providers.""" """A base class for user providers."""
def _get_user(self, username, password, role): def _get_user(self, username, role):
return { return {
'username': username, 'username': username,
'group': None, 'group': None,
'password': password, 'password': None,
'roles': [role]} 'roles': [role]}
@ -45,7 +45,7 @@ class ClientUserProvider(UserProvider):
def user(self, username): def user(self, username):
print 'checking %s' % username print 'checking %s' % username
if username == 'dummy': if username == 'dummy':
return self._get_user(username, username, 'client') return self._get_user(username, 'client')
return AuthKitNoSuchUserError() return AuthKitNoSuchUserError()
def list_roles(self): def list_roles(self):

View File

@ -13,3 +13,15 @@ cover-package=gnuviechadmin
pdb=1 pdb=1
pdb-failures=1 pdb-failures=1
verbosity=3 verbosity=3
[checksum]
per-file=1
md5=1
sha=1
sign=1
[pudge]
dest=apidoc
license=gnu
modules=gnuviechadmin
title=GNUViechAdmin

View File

@ -21,6 +21,12 @@
from setuptools import setup, find_packages from setuptools import setup, find_packages
try:
import pudge
import buildutils
except ImportError:
pass
setup( setup(
name = 'gnuviechadmin', name = 'gnuviechadmin',
version = '0.1', version = '0.1',