gislab-npo / gislab

GIS.lab - total reduction of deployment and maintenance costs for complete free and open source geospatial infrastructure
http://gislab-npo.github.io/gislab/
GNU General Public License v3.0
39 stars 14 forks source link

GIS.lab user Python library #334

Open imincik opened 9 years ago

imincik commented 9 years ago

Development of Python library which will allow to list and manage GIS.lab user's accounts and will replace Bash code in gislab-adduser|deluser|password .

NOTES:

class GISLabUserError(Exception):
    pass

class GISLabUser:
    """GISLab user

    :param username: user name (must be unique)
    :param first_name: first name (required)
    :param last_name: last name (required)
    :param email: email (required) - validated, must be unique
    :param password: user password if not given than automatically generated
    :param superuser: True to add user to superuser's group
    :param description: user description (optional)
    """
    def __init__(self, username, first_name, last_name, email,
                 password=None,  superuser=False, description=None):
        pass

    def __getattr__(self, name):
        pass

    def __setattr__(self, name):
        pass

    def _generate_password(self):
        """Generate new password for the user
        """
        pass

    def _validate_username(self):
        """Do user name validation

        Throws GISLabUserError on failure
        """

    def _validate_email(self):
        """Do email validation and test if the same email address is not already assigned to existing user 

        Throws GISLabUserError on failure.
        """
        pass

    def get_username(self):
        """Returns the username for the user

        :return: username as string
        """
        pass

    def get_full_name(self):
        """Returns the first_name plus the last_name, with a space in between

        :return: full user name as string
        """
        pass

    def get_short_name(self):
        """Returns the firtst_name

        :return: first_name as string
        """
        pass

    def is_superuser(self):
        """Return True if user account has superuser privileges, otherwise return False

        :return: True if user account has superuser privileges, otherwise return False
        """
        pass

    def is_connected(self):
        """Check if the user is connected or running some process on the server

        :return: True if connected otherwise False
        """
        pass

    def is_active(self):
        """Return True if user account is active, otherwise return False

        :return: True if account is active otherwise False
        """
        pass

    def email_user(self, subject, message):
        """Sends an email to the user. 

        :return: True if email was sent, otherwise False
        """
        pass

    @property
    def date_joined(self):
        """Return datetime designating when the account was created - TODO: require LDAP schama update

    :return: datetime when the account was created
    """
    pass

class GISLab:
    """Main GIS.lab class"""
    def __init__(self):
        pass

    def __iter__(self):
        pass

    def useradd(self, username):
        """Create GIS.lab user account.

         * creates empty LDAP account
         * enable forwarding system mails (only for superusers)
         * creates PostgreSQL user account
         * creates publishing directory
         * saves user credentials to hidden directory in home folder

        Throw GISLabUserError on failure.

        :return: instance of GISLabUser
        """
        pass

    def userdel(self, username):
        """Delete GIS.lab user account.

        :return: True
        """
        pass

    def userslist(self):
        """Get list of existing GIS.lab user accounts.

        :return: list of GISLabUser objects
        """
        pass

    def userget(self, username):
        """Get GISLab user

        :param username: user name

        :return: GISLabUser instance or None
        """
        pass

    def _useraddLDAP(self, user):
        pass

    def _useraddPostgreSQL(self, user):
        pass

    def _useraddPublishDirectory(self, user):
        pass

    def machineadd(self, mac):
        """Add GIS.lab client machine to list of known machines.

        :return: True
        """
        pass

    def machinedel(self, mac):
        """Remove GIS.lab client machine from list of known machines.

        :return: True
        """
        pass

    def machineslist(self):
        """Get list of known GIS.lab client machines.

        :return: list of MAC addresses
        """
        pass
marcel-dancak commented 9 years ago

Momentalne to vyzera tak, ze objekt triedy GISLab by bol bezstavovy, a preto by som navrhol pouzit dekorator @staticmethod. Vsetky administratorske funkcie by tymto boli definovane v jednom logickom celku a nemusela by sa vytvarat instancia objektu.

>>> import GISLab
>>> GISLab.useradd(...)
>>> GISLab.usermod(...)

class GISLab(object):

    @staticmethod
    def useradd(username, *kwargs):
        return GISLabUser.create(username, *kwargs)

    @staticmethod
    def userdel(username):
        GISLabUser.get(username).delete()

    @staticmethod
    def usermod(username, **kwargs):
        GISLabUser.get(username).modify(**kwargs)

    @staticmethod
    def userget(username):
        return GISLabUser.get(username)

    @staticmethod
    def userslist():
        return GISLabUser.users(query)

V triede GISLabUser by som pouzival jej konstruktor iba interne, na vytvaranie novych a ziskavanie uz existujucich pouzivatelov by som vytvoril metody triedy (dekorator @classmethod), ktore by vzdy vracali uz inicializovane objekty pouzivatelov (atribut GISLabUser._initialized by uz nebol potrebny).

class GISLabUser(object):
    @classmethod
    def create(cls, username, firstname, lastname, email, password, description, superuser):
        user = cls(username, firstname=firstname, lastname=lastname, email=email, password=password, description=description, superuser=superuser)
        user.uid = nextuid()
        user.gid = 
        user.home = 
        user.published_data = 
        ...
        user._create_ldap()
        user._create_postgres()
        user._create_dirs(uid, gid, home, published_data)

        return user

    @classmethod
    def users(cls, query=None):
        if not query:
            # all gislab users
            gid = grp.getgrnam('gislabusers').gr_gid
            query = "(&(objectClass=inetOrgPerson)(gidNumber={}))".format(gid)

        users = []
        for ldap_item in ... :
            username = ldap_item[1]['uid'][0]
            data = ldap_item[0][1]
            firstname = data['givenName'][0]
            ...
            user = cls(username, firstname=firstname, ...)
            users.append(user)
        return users

    @classmethod
    def get(cls, username):
        query = "(uid={})".format(username)
        users = GISLabUser.users(query)
        if users is None or len(users) == 0:
            raise GISLabError("GIS.lab user '{0}' doesn't exists".format(username))
        return users[0]

    def __init__(self, username, **kwargs):
        self.username = self._validate_username(username)
        self._log = "GISLabUser(%s): " % self.username
        for name, value in kwargs.iteritems():
            setattr(self, name, value)

    def _create_ldap(self):
        ...