1
0
Fork 0
mirror of https://github.com/YunoHost/moulinette.git synced 2024-09-03 20:06:31 +02:00

Update and review yunohost.user

This commit is contained in:
Jerome Lebleu 2014-03-27 03:03:14 +01:00
parent 447748175e
commit 8be16b85fa
2 changed files with 208 additions and 209 deletions
data/actionsmap
lib/yunohost

View file

@ -49,6 +49,7 @@ _global:
parameters: parameters:
uri: ldap://localhost:389 uri: ldap://localhost:389
base_dn: dc=yunohost,dc=org base_dn: dc=yunohost,dc=org
argument_auth: true
arguments: arguments:
-v: -v:
full: --version full: --version
@ -67,6 +68,8 @@ user:
list: list:
action_help: List users action_help: List users
api: GET /users api: GET /users
configuration:
authenticate: all
arguments: arguments:
--fields: --fields:
help: fields to fetch help: fields to fetch
@ -77,14 +80,18 @@ user:
-l: -l:
full: --limit full: --limit
help: Maximum number of user fetched help: Maximum number of user fetched
type: int
-o: -o:
full: --offset full: --offset
help: Starting number for user fetching help: Starting number for user fetching
type: int
### user_create() ### user_create()
create: create:
action_help: Create user action_help: Create user
api: POST /users api: POST /users
configuration:
authenticate: all
arguments: arguments:
-u: -u:
full: --username full: --username
@ -119,6 +126,8 @@ user:
delete: delete:
action_help: Delete user action_help: Delete user
api: 'DELETE /users/<users>' api: 'DELETE /users/<users>'
configuration:
authenticate: all
arguments: arguments:
-u: -u:
full: --users full: --users
@ -136,6 +145,8 @@ user:
update: update:
action_help: Update user informations action_help: Update user informations
api: 'PUT /users/<username>' api: 'PUT /users/<username>'
configuration:
authenticate: all
arguments: arguments:
username: username:
help: Username of user to update help: Username of user to update
@ -170,6 +181,8 @@ user:
info: info:
action_help: Get user informations action_help: Get user informations
api: 'GET /users/<username>' api: 'GET /users/<username>'
configuration:
authenticate: all
arguments: arguments:
username: username:
help: Username or mail to get informations help: Username or mail to get informations

View file

@ -2,7 +2,7 @@
""" License """ License
Copyright (C) 2013 YunoHost Copyright (C) 2014 YUNOHOST.ORG
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published it under the terms of the GNU Affero General Public License as published
@ -23,22 +23,18 @@
Manage users Manage users
""" """
import logging
logging.warning('the module yunohost.user has not been revisited and updated yet')
import os import os
import sys import sys
import ldap
import crypt import crypt
import random import random
import string import string
import getpass from moulinette.core import MoulinetteError
from domain import domain_list
from hook import hook_callback
from moulinette.helpers import YunoHostError, YunoHostLDAP, win_msg, colorize, validate, get_required_args from yunohost.domain import domain_list
from yunohost.hook import hook_callback
def user_list(fields=None, filter=None, limit=None, offset=None):
def user_list(auth, fields=None, filter=None, limit=None, offset=None):
""" """
List users List users
@ -49,47 +45,44 @@ def user_list(fields=None, filter=None, limit=None, offset=None):
fields -- fields to fetch fields -- fields to fetch
""" """
with YunoHostLDAP() as yldap: user_attrs = { 'uid': 'username',
user_attrs = ['uid', 'mail', 'cn', 'maildrop'] 'cn': 'fullname',
'mail': 'mail',
'maildrop': 'mail-forward' }
attrs = [] attrs = []
result_list = [] result_list = []
if offset: offset = int(offset)
else: offset = 0 # Set default arguments values
if limit: limit = int(limit) if offset is None:
else: limit = 1000 offset = 0
if not filter: filter = 'uid=*' if limit is None:
limit = 1000
if filter is None:
filter = '(&(objectclass=person)(!(uid=root))(!(uid=nobody)))'
if fields: if fields:
for attr in fields.items(): for attr in user_attrs.keys():
if attr in user_attrs: if attr in fields:
attrs.append(attr) attrs.append(attr)
continue
else: else:
raise YunoHostError(22, _("Invalid field : ") + attr) raise MoulinetteError(22, _("Invalid field '%s'") % attr)
else: else:
attrs = user_attrs attrs = [ 'uid', 'cn', 'mail' ]
result = yldap.search('ou=users,dc=yunohost,dc=org', filter, attrs) result = auth.search('ou=users,dc=yunohost,dc=org', filter, attrs)
if result and len(result) > (0 + offset) and limit > 0:
i = 0 + offset
for user in result[i:]:
if i - offset < limit:
if user['uid'][0] == 'root' or user['uid'][0] == 'nobody':
continue
entry = {
'Username': user['uid'][0],
'Fullname': user['cn'][0],
}
if 'mail' in user.keys():
entry['Mail'] = user['mail'][0]
if len(result) > offset and limit > 0:
for user in result[offset:offset+limit]:
entry = {}
for attr, values in user.items():
try:
entry[user_attrs[attr]] = values[0]
except:
pass
result_list.append(entry) result_list.append(entry)
i += 1 return { 'users' : result_list }
return { 'Users' : result_list }
def user_create(username, firstname, lastname, mail, password): def user_create(auth, username, firstname, lastname, mail, password):
""" """
Create user Create user
@ -101,18 +94,17 @@ def user_create(username, firstname, lastname, mail, password):
password password
""" """
with YunoHostLDAP() as yldap:
# Validate password length # Validate password length
if len(password) < 4: if len(password) < 4:
raise YunoHostError(22, _("Password is too short")) raise MoulinetteError(22, _("Password is too short"))
yldap.validate_uniqueness({ auth.validate_uniqueness({
'uid' : username, 'uid' : username,
'mail' : mail 'mail' : mail
}) })
if mail[mail.find('@')+1:] not in domain_list()['Domains']: if mail[mail.find('@')+1:] not in domain_list()['Domains']:
raise YunoHostError(22, _("Domain not found : ")+ mail[mail.find('@')+1:]) raise MoulinetteError(22, _("Unknown domain '%s'") % mail[mail.find('@')+1:])
# Get random UID/GID # Get random UID/GID
@ -146,19 +138,19 @@ def user_create(username, firstname, lastname, mail, password):
} }
if yldap.add(rdn, attr_dict): if auth.add(rdn, attr_dict):
os.system("su - " + username + " -c ''") os.system("su - " + username + " -c ''")
os.system('yunohost app ssowatconf > /dev/null 2>&1') os.system('yunohost app ssowatconf > /dev/null 2>&1')
#TODO: Send a welcome mail to user #TODO: Send a welcome mail to user
win_msg(_("User successfully created")) msignals.display(_("User '%s' successfully created.") % username, 'success')
hook_callback('post_user_create', [username, mail, password, firstname, lastname]) hook_callback('post_user_create', [username, mail, password, firstname, lastname])
return { _("Fullname") : fullname, _("Username") : username, _("Mail") : mail } return { 'fullname' : fullname, 'username' : username, 'mail' : mail }
else: else:
raise YunoHostError(169, _("An error occured during user creation")) raise MoulinetteError(169, _("An error occurred during user creation"))
def user_delete(users, purge=False): def user_delete(auth, users, purge=False):
""" """
Delete user Delete user
@ -167,27 +159,25 @@ def user_delete(users, purge=False):
purge purge
""" """
with YunoHostLDAP() as yldap:
result = { 'Users' : [] }
if not isinstance(users, list): if not isinstance(users, list):
users = [ users ] users = [ users ]
deleted = []
for user in users: for user in users:
if yldap.remove('uid=' + user+ ',ou=users'): if auth.remove('uid=' + user + ',ou=users'):
if purge: if purge:
os.system('rm -rf /home/' + user) os.system('rm -rf /home/' + user)
result['Users'].append(user) deleted.append(user)
continue continue
else: else:
raise YunoHostError(169, _("An error occured during user deletion")) raise MoulinetteError(169, _("An error occurred during user deletion"))
os.system('yunohost app ssowatconf > /dev/null 2>&1') os.system('yunohost app ssowatconf > /dev/null 2>&1')
win_msg(_("User(s) successfully deleted")) msignals.display(_("User(s) successfully deleted."), 'success')
return result return { 'users': deleted }
def user_update(username, firstname=None, lastname=None, mail=None, change_password=None, add_mailforward=None, remove_mailforward=None, add_mailalias=None, remove_mailalias=None): def user_update(auth, username, firstname=None, lastname=None, mail=None, change_password=None, add_mailforward=None, remove_mailforward=None, add_mailalias=None, remove_mailalias=None):
""" """
Update user informations Update user informations
@ -203,15 +193,14 @@ def user_update(username, firstname=None, lastname=None, mail=None, change_passw
remove_mailalias -- Mail aliases to remove remove_mailalias -- Mail aliases to remove
""" """
with YunoHostLDAP() as yldap:
attrs_to_fetch = ['givenName', 'sn', 'mail', 'maildrop'] attrs_to_fetch = ['givenName', 'sn', 'mail', 'maildrop']
new_attr_dict = {} new_attr_dict = {}
domains = domain_list()['Domains'] domains = domain_list()['Domains']
# Populate user informations # Populate user informations
result = yldap.search(base='ou=users,dc=yunohost,dc=org', filter='uid=' + username, attrs=attrs_to_fetch) result = auth.search(base='ou=users,dc=yunohost,dc=org', filter='uid=' + username, attrs=attrs_to_fetch)
if not result: if not result:
raise YunoHostError(167, _("No user found")) raise MoulinetteError(167, _("Unknown username '%s'") % username)
user = result[0] user = result[0]
# Get modifications from arguments # Get modifications from arguments
@ -233,9 +222,9 @@ def user_update(username, firstname=None, lastname=None, mail=None, change_passw
new_attr_dict['userPassword'] = '{CRYPT}' + crypt.crypt(str(change_password), salt) new_attr_dict['userPassword'] = '{CRYPT}' + crypt.crypt(str(change_password), salt)
if mail: if mail:
yldap.validate_uniqueness({ 'mail': mail }) auth.validate_uniqueness({ 'mail': mail })
if mail[mail.find('@')+1:] not in domains: if mail[mail.find('@')+1:] not in domains:
raise YunoHostError(22, _("Domain not found : ")+ mail[mail.find('@')+1:]) raise MoulinetteError(22, _("Unknown domain '%s'") % mail[mail.find('@')+1:])
del user['mail'][0] del user['mail'][0]
new_attr_dict['mail'] = [mail] + user['mail'] new_attr_dict['mail'] = [mail] + user['mail']
@ -243,9 +232,9 @@ def user_update(username, firstname=None, lastname=None, mail=None, change_passw
if not isinstance(add_mailalias, list): if not isinstance(add_mailalias, list):
add_mailalias = [ add_mailalias ] add_mailalias = [ add_mailalias ]
for mail in add_mailalias: for mail in add_mailalias:
yldap.validate_uniqueness({ 'mail': mail }) auth.validate_uniqueness({ 'mail': mail })
if mail[mail.find('@')+1:] not in domains: if mail[mail.find('@')+1:] not in domains:
raise YunoHostError(22, _("Domain not found : ")+ mail[mail.find('@')+1:]) raise MoulinetteError(22, _("Unknown domain '%s'") % mail[mail.find('@')+1:])
user['mail'].append(mail) user['mail'].append(mail)
new_attr_dict['mail'] = user['mail'] new_attr_dict['mail'] = user['mail']
@ -256,7 +245,7 @@ def user_update(username, firstname=None, lastname=None, mail=None, change_passw
if len(user['mail']) > 1 and mail in user['mail'][1:]: if len(user['mail']) > 1 and mail in user['mail'][1:]:
user['mail'].remove(mail) user['mail'].remove(mail)
else: else:
raise YunoHostError(22, _("Invalid mail alias : ") + mail) raise MoulinetteError(22, _("Invalid mail alias '%s'") % mail)
new_attr_dict['mail'] = user['mail'] new_attr_dict['mail'] = user['mail']
if add_mailforward: if add_mailforward:
@ -275,18 +264,17 @@ def user_update(username, firstname=None, lastname=None, mail=None, change_passw
if len(user['maildrop']) > 1 and mail in user['maildrop'][1:]: if len(user['maildrop']) > 1 and mail in user['maildrop'][1:]:
user['maildrop'].remove(mail) user['maildrop'].remove(mail)
else: else:
raise YunoHostError(22, _("Invalid mail forward : ") + mail) raise MoulinetteError(22, _("Invalid mail forward '%s'") % mail)
new_attr_dict['maildrop'] = user['maildrop'] new_attr_dict['maildrop'] = user['maildrop']
if yldap.update('uid=' + username + ',ou=users', new_attr_dict): if auth.update('uid=' + username + ',ou=users', new_attr_dict):
win_msg(_("User successfully updated")) msignals.display(_("User '%s' successfully updated.") % username, 'success')
return user_info(username) return user_info(username)
else: else:
raise YunoHostError(169, _("An error occured during user update")) raise MoulinetteError(169, _("An error occurred during user update"))
def user_info(auth, username):
def user_info(username):
""" """
Get user informations Get user informations
@ -294,7 +282,6 @@ def user_info(username):
username -- Username or mail to get informations username -- Username or mail to get informations
""" """
with YunoHostLDAP() as yldap:
user_attrs = ['cn', 'mail', 'uid', 'maildrop', 'givenName', 'sn'] user_attrs = ['cn', 'mail', 'uid', 'maildrop', 'givenName', 'sn']
if len(username.split('@')) is 2: if len(username.split('@')) is 2:
@ -302,29 +289,28 @@ def user_info(username):
else: else:
filter = 'uid='+ username filter = 'uid='+ username
result = yldap.search('ou=users,dc=yunohost,dc=org', filter, user_attrs) result = auth.search('ou=users,dc=yunohost,dc=org', filter, user_attrs)
if result: if result:
user = result[0] user = result[0]
else: else:
raise YunoHostError(22, _("Unknown user/mail : ") + username) raise MoulinetteError(22, _("Unknown username/mail '%s'") % username)
result_dict = { result_dict = {
'Username': user['uid'][0], 'username': user['uid'][0],
'Fullname': user['cn'][0], 'fullname': user['cn'][0],
'Firstname': user['givenName'][0], 'firstname': user['givenName'][0],
'Lastname': user['sn'][0], 'lastname': user['sn'][0],
'Mail': user['mail'][0] 'mail': user['mail'][0]
} }
if len(user['mail']) > 1: if len(user['mail']) > 1:
result_dict['Mail Aliases'] = user['mail'][1:] result_dict['mail-aliases'] = user['mail'][1:]
if len(user['maildrop']) > 1: if len(user['maildrop']) > 1:
result_dict['Mail Forward'] = user['maildrop'][1:] result_dict['mail-forward'] = user['maildrop'][1:]
if result: if result:
return result_dict return result_dict
else: else:
raise YunoHostError(167, _("No user found")) raise MoulinetteError(167, _("No user found"))