mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
user_add function
This commit is contained in:
parent
7e701b03f9
commit
5dbce99e65
4 changed files with 114 additions and 16 deletions
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import ldap
|
import ldap
|
||||||
|
import ldap.modlist as modlist
|
||||||
|
import re
|
||||||
import getpass
|
import getpass
|
||||||
import yunohost_messages as msg
|
import yunohost_messages as msg
|
||||||
|
|
||||||
|
@ -18,7 +20,7 @@ class YunoHostLDAP:
|
||||||
self.conn.simple_bind_s('cn=admin,' + self.base, self.pwd)
|
self.conn.simple_bind_s('cn=admin,' + self.base, self.pwd)
|
||||||
except ldap.INVALID_CREDENTIALS:
|
except ldap.INVALID_CREDENTIALS:
|
||||||
print(msg.error + _('Wrong credentials'))
|
print(msg.error + _('Wrong credentials'))
|
||||||
sys.exit(1)
|
sys.exit(msg.ECONNREFUSED)
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
""" Unbind from LDAP """
|
""" Unbind from LDAP """
|
||||||
|
@ -26,7 +28,7 @@ class YunoHostLDAP:
|
||||||
try:
|
try:
|
||||||
self.conn.unbind_s()
|
self.conn.unbind_s()
|
||||||
except:
|
except:
|
||||||
print(msg.error + _('A problem occured on LDAP unbind'))
|
print(msg.error + _('A problem occured during LDAP unbind'))
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
@ -38,9 +40,9 @@ class YunoHostLDAP:
|
||||||
base = self.base
|
base = self.base
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = self.conn.search_s(base, ldap.SCOPE_ONELEVEL, filter, attrs)
|
result = self.conn.search_s(base, ldap.SCOPE_SUBTREE, filter, attrs)
|
||||||
except Exception:
|
except:
|
||||||
print(msg.error + _('An error occured on LDAP search'))
|
print(msg.error + _('An error occured during LDAP search'))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
|
@ -51,5 +53,38 @@ class YunoHostLDAP:
|
||||||
result_list.append(entry)
|
result_list.append(entry)
|
||||||
return result_list
|
return result_list
|
||||||
else:
|
else:
|
||||||
print(_('No result found'))
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def add(self, rdn, attr_dict):
|
||||||
|
""" Add LDAP entry """
|
||||||
|
|
||||||
|
dn = rdn + ',' + self.base
|
||||||
|
ldif = modlist.addModlist(attr_dict)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.conn.add_s(dn, ldif)
|
||||||
|
except:
|
||||||
|
print(msg.error + _('An error occured during LDAP entry creation'))
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def validate(self, regex_dict):
|
||||||
|
for attr, pattern in regex_dict.items():
|
||||||
|
if re.match(pattern, attr):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
print(msg.error + _('Invalid value') + ' "' + attr + '"')
|
||||||
|
sys.exit(msg.EINVAL)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def validate_uniqueness(self, value_dict):
|
||||||
|
for attr, value in value_dict.items():
|
||||||
|
if not self.search(filter=attr + '=' + value):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
print(msg.error + _('Attribute already exists') + ' "' + attr + '=' + value + '"')
|
||||||
|
sys.exit(msg.EEXIST)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
error = "\033[31m\033[1m" + _("Error:") + "\033[m "
|
""" Colored status messages """
|
||||||
interrupt = "\033[31m\033[1m" + _("Interrupt:") + "\033[m "
|
error = "\033[31m\033[1m" + _("Error:") + "\033[m " # Red
|
||||||
notice = "\033[34m\033[1m" + _("Notice:") + "\033[m "
|
interrupt = "\033[31m\033[1m" + _("Interrupt:") + "\033[m " # Red
|
||||||
success = "\033[33m\033[1m" + _("Success:") + "\033[m "
|
notice = "\033[34m\033[1m" + _("Notice:") + "\033[m " # Cyan
|
||||||
|
success = "\033[32m\033[1m" + _("Success:") + "\033[m " # Green
|
||||||
|
|
||||||
|
|
||||||
|
""" Error codes """
|
||||||
|
EACCES = 13 # Permission denied
|
||||||
|
EEXIST = 17 # Exists
|
||||||
|
EINVAL = 22 # Invalid argument
|
||||||
|
EUSERS = 87 # Too many users
|
||||||
|
ECONNREFUSED = 111 # Connection refused
|
||||||
|
EDQUOTA = 122 # Quota exceeded
|
||||||
|
ECANCELED = 125 # Operation Canceled
|
||||||
|
ENOTFOUND = 167 # Not found
|
||||||
|
EUNDEFINED = 168 # Undefined
|
||||||
|
ELDAP = 169 # LDAP operation error
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import ldap
|
import ldap
|
||||||
import ldap.modlist as modlist
|
|
||||||
import yunohost_ldap
|
import yunohost_ldap
|
||||||
import yunohost_messages as msg
|
import yunohost_messages as msg
|
||||||
|
import crypt
|
||||||
|
import random
|
||||||
|
import string
|
||||||
import getpass
|
import getpass
|
||||||
|
|
||||||
# Initialize LDAP
|
# Initialize LDAP
|
||||||
|
@ -16,8 +18,18 @@ def user_list(args): # TODO : fix
|
||||||
|
|
||||||
|
|
||||||
def user_add(args):
|
def user_add(args):
|
||||||
|
"""
|
||||||
|
Add user to LDAP
|
||||||
|
|
||||||
|
Keyword argument:
|
||||||
|
args -- Dictionnary of values (can be empty)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Boolean
|
||||||
|
"""
|
||||||
required_args = ['username', 'mail', 'firstname', 'lastname']
|
required_args = ['username', 'mail', 'firstname', 'lastname']
|
||||||
|
|
||||||
|
# Input missing values
|
||||||
try:
|
try:
|
||||||
for arg in required_args:
|
for arg in required_args:
|
||||||
if not args[arg]:
|
if not args[arg]:
|
||||||
|
@ -28,11 +40,48 @@ def user_add(args):
|
||||||
pwd2 = getpass.getpass('Retype password:')
|
pwd2 = getpass.getpass('Retype password:')
|
||||||
if args['password'] != pwd2:
|
if args['password'] != pwd2:
|
||||||
print(msg.error + _("Passwords doesn't match"))
|
print(msg.error + _("Passwords doesn't match"))
|
||||||
sys.exit(1)
|
sys.exit(msg.EINVAL)
|
||||||
except KeyboardInterrupt, EOFError:
|
except KeyboardInterrupt, EOFError:
|
||||||
print("\n" + msg.interrupt + _("User not created"))
|
print("\n" + msg.interrupt + _("User not created"))
|
||||||
sys.exit(1)
|
sys.exit(msg.ECANCELED)
|
||||||
|
|
||||||
|
# Manage values
|
||||||
|
fullname = args['firstname'] + ' ' + args['lastname']
|
||||||
|
rdn = 'cn=' + fullname + ',ou=users'
|
||||||
|
char_set = string.ascii_uppercase + string.digits
|
||||||
|
salt = ''.join(random.sample(char_set,8))
|
||||||
|
salt = '$1$' + salt + '$'
|
||||||
|
pwd = "{CRYPT}" + crypt.crypt(str(args['password']), salt)
|
||||||
|
attr_dict = {
|
||||||
|
'objectClass' : ['mailAccount', 'inetOrgPerson'],
|
||||||
|
'givenName' : args['firstname'],
|
||||||
|
'sn' : args['lastname'],
|
||||||
|
'displayName' : fullname,
|
||||||
|
'cn' : fullname,
|
||||||
|
'uid' : args['username'],
|
||||||
|
'mail' : args['mail'],
|
||||||
|
'userPassword' : pwd
|
||||||
|
}
|
||||||
|
|
||||||
print(args)
|
# Validate values
|
||||||
|
yldap.validate({
|
||||||
|
args['username'] : r'^[a-z0-9_]+$',
|
||||||
|
args['mail'] : r'^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$'
|
||||||
|
})
|
||||||
|
|
||||||
|
yldap.validate_uniqueness({
|
||||||
|
'uid' : args['username'],
|
||||||
|
'cn' : fullname,
|
||||||
|
'mail' : args['mail'],
|
||||||
|
'mailalias' : args['mail']
|
||||||
|
})
|
||||||
|
|
||||||
|
if yldap.add(rdn, attr_dict):
|
||||||
|
print('\n ' + msg.success + _('User successfully created') + '\n')
|
||||||
|
for attr, value in attr_dict.items():
|
||||||
|
if attr != 'objectClass':
|
||||||
|
print('\033[35m\033[1m ' + attr + ': \033[m' + value)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(msg.error + _('An error occured during user creation'))
|
||||||
|
return False
|
||||||
|
|
4
yunohost
4
yunohost
|
@ -49,7 +49,7 @@ def str_to_func(astr):
|
||||||
func = getattr(mod, function)
|
func = getattr(mod, function)
|
||||||
except NameError:
|
except NameError:
|
||||||
print(msg.error + _('Function is not defined'))
|
print(msg.error + _('Function is not defined'))
|
||||||
sys.exit(1)
|
sys.exit(msg.EUNDEFINED)
|
||||||
else:
|
else:
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ def dict_to_parsers(action_dict):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Intialize parsers
|
# Intialize parsers
|
||||||
parsers = subparsers_category = subparsers_action = dict()
|
parsers = subparsers_category = subparsers_action = {}
|
||||||
parsers['general'] = argparse.ArgumentParser()
|
parsers['general'] = argparse.ArgumentParser()
|
||||||
subparsers = parsers['general'].add_subparsers()
|
subparsers = parsers['general'].add_subparsers()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue