8
0
Fork 0
mirror of https://gitlab.federez.net/re2o/re2o synced 2024-06-18 08:38:09 +00:00

First step of docstring translation

This commit is contained in:
Gabriel Detraz 2020-04-25 03:36:27 +02:00
parent 87022a7b04
commit 02678b7ccd
9 changed files with 300 additions and 75 deletions

View file

@ -21,9 +21,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Regroupe les fonctions transversales utiles Global independant usefull functions
Et non corrélées/dépendantes des autres applications
""" """
import smtplib import smtplib

View file

@ -19,7 +19,7 @@
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., # with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Fonction de context, variables renvoyées à toutes les vues""" """Context functions, runs and results sends globaly to all templates"""
from __future__ import unicode_literals from __future__ import unicode_literals
@ -34,8 +34,12 @@ from re2o.settings_local import OPTIONNAL_APPS_RE2O
def context_user(request): def context_user(request):
"""Fonction de context lorsqu'un user est logué (ou non), """Global Context function
renvoie les infos sur l'user, la liste de ses droits, ses machines"""
Returns:
dict:Containing user's interfaces and himself if logged, else None
"""
user = request.user user = request.user
if get_language() == "fr": if get_language() == "fr":
global_message = GeneralOption.get_cached_value("general_message_fr") global_message = GeneralOption.get_cached_value("general_message_fr")
@ -61,8 +65,13 @@ def context_user(request):
def context_optionnal_apps(request): def context_optionnal_apps(request):
"""Fonction de context pour générer la navbar en fonction des """Context functions. Called to add optionnal apps buttons in navbari
apps optionnels"""
Returns:
dict:Containing optionnal template list of functions for navbar found
in optional apps
"""
optionnal_apps = [import_module(app) for app in OPTIONNAL_APPS_RE2O] optionnal_apps = [import_module(app) for app in OPTIONNAL_APPS_RE2O]
optionnal_templates_navbar_user_list = [ optionnal_templates_navbar_user_list = [
app.views.navbar_user() app.views.navbar_user()

View file

@ -85,7 +85,13 @@ class FieldPermissionModelMixin:
class FieldPermissionFormMixin: class FieldPermissionFormMixin:
""" """
Construit le formulaire et retire les champs interdits Build a form, and remove all forbiden fields
Parameters:
user:Build-in with a Django Form instance, and parameter user in kwargs,
representing calling user for this form. Then test if a field is forbiden
or not with has_field_paremeter model function
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

View file

@ -45,7 +45,14 @@ DIGEST_LEN = 20
def makeSecret(password): def makeSecret(password):
""" Build a hashed and salted version of the password """ """ Build a hashed and salted version of the password with SSHA
Parameters:
password (string): Password to hash
Returns:
string: Hashed password
"""
salt = os.urandom(4) salt = os.urandom(4)
h = hashlib.sha1(password.encode()) h = hashlib.sha1(password.encode())
h.update(salt) h.update(salt)
@ -53,13 +60,30 @@ def makeSecret(password):
def hashNT(password): def hashNT(password):
""" Build a md4 hash of the password to use as the NT-password """ """ Build a md4 hash of the password to use as the NT-password
Parameters:
password (string): Password to hash
Returns:
string: Hashed password
"""
hash_str = hashlib.new("md4", password.encode("utf-16le")).digest() hash_str = hashlib.new("md4", password.encode("utf-16le")).digest()
return binascii.hexlify(hash_str).upper() return binascii.hexlify(hash_str).upper()
def checkPassword(challenge_password, password): def checkPassword(challenge_password, password):
""" Check if a given password match the hash of a stored password """ """Check if a given password match the hash of a stored password
Parameters:
challenge_password (string): Password to verify with hash
password (string): Hashed password to verify
Returns:
boolean: True if challenge_password and password match
"""
challenge_bytes = decodestring(challenge_password[ALGO_LEN:].encode()) challenge_bytes = decodestring(challenge_password[ALGO_LEN:].encode())
digest = challenge_bytes[:DIGEST_LEN] digest = challenge_bytes[:DIGEST_LEN]
salt = challenge_bytes[DIGEST_LEN:] salt = challenge_bytes[DIGEST_LEN:]
@ -69,7 +93,15 @@ def checkPassword(challenge_password, password):
def hash_password_salt(hashed_password): def hash_password_salt(hashed_password):
""" Extract the salt from a given hashed password """ """ Extract the salt from a given hashed password
Parameters:
hashed_password (string): Hashed password to extract salt
Returns:
string: Salt of the password
"""
if hashed_password.upper().startswith("{CRYPT}"): if hashed_password.upper().startswith("{CRYPT}"):
hashed_password = hashed_password[7:] hashed_password = hashed_password[7:]
if hashed_password.startswith("$"): if hashed_password.startswith("$"):
@ -243,6 +275,14 @@ class SSHAPasswordHasher(hashers.BasePasswordHasher):
class RecryptBackend(ModelBackend): class RecryptBackend(ModelBackend):
"""Function for legacy users. During auth, if their hash password is different from SSHA or ntlm
password is empty, rehash in SSHA or NTLM
Returns:
model user instance: Instance of the user logged
"""
def authenticate(self, username=None, password=None): def authenticate(self, username=None, password=None):
# we obtain from the classical auth backend the user # we obtain from the classical auth backend the user
user = super(RecryptBackend, self).authenticate(None, username, password) user = super(RecryptBackend, self).authenticate(None, username, password)

View file

@ -22,7 +22,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Jean-Romain Garnier # Jean-Romain Garnier
""" """
Regroupe les fonctions en lien avec les mails All functions linked with emails here. Non model or app dependant
""" """
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _

View file

@ -93,16 +93,27 @@ class AclMixin(object):
@classmethod @classmethod
def get_instance(cls, object_id, *_args, **kwargs): def get_instance(cls, object_id, *_args, **kwargs):
"""Récupère une instance """Get an instance from its id.
:return: Une instance de la classe évidemment"""
Parameters:
object_id (int): Id of the instance to find
Returns:
Django instance: Instance of this class
"""
return cls.objects.get(pk=object_id) return cls.objects.get(pk=object_id)
@classmethod @classmethod
def can_create(cls, user_request, *_args, **_kwargs): def can_create(cls, user_request, *_args, **_kwargs):
"""Verifie que l'user a les bons droits pour créer """Check if a user has the right to create an object
un object
:param user_request: instance utilisateur qui fait la requête Parameters:
:return: soit True, soit False avec la raison de l'échec""" user_request: User calling for this action
Returns:
Boolean: True if user_request has the right access to do it, else
false with reason for reject authorization
"""
permission = cls.get_modulename() + ".add_" + cls.get_classname() permission = cls.get_modulename() + ".add_" + cls.get_classname()
can = user_request.has_perm(permission) can = user_request.has_perm(permission)
return ( return (
@ -114,11 +125,16 @@ class AclMixin(object):
) )
def can_edit(self, user_request, *_args, **_kwargs): def can_edit(self, user_request, *_args, **_kwargs):
"""Verifie que l'user a les bons droits pour editer """Check if a user has the right to edit an instance
cette instance
:param self: Instance à editer Parameters:
:param user_request: Utilisateur qui fait la requête user_request: User calling for this action
:return: soit True, soit False avec la raison de l'échec""" self: Instance to edit
Returns:
Boolean: True if user_request has the right access to do it, else
false with reason for reject authorization
"""
permission = self.get_modulename() + ".change_" + self.get_classname() permission = self.get_modulename() + ".change_" + self.get_classname()
can = user_request.has_perm(permission) can = user_request.has_perm(permission)
return ( return (
@ -130,11 +146,16 @@ class AclMixin(object):
) )
def can_delete(self, user_request, *_args, **_kwargs): def can_delete(self, user_request, *_args, **_kwargs):
"""Verifie que l'user a les bons droits pour delete """Check if a user has the right to delete an instance
cette instance
:param self: Instance à delete Parameters:
:param user_request: Utilisateur qui fait la requête user_request: User calling for this action
:return: soit True, soit False avec la raison de l'échec""" self: Instance to delete
Returns:
Boolean: True if user_request has the right access to do it, else
false with reason for reject authorization
"""
permission = self.get_modulename() + ".delete_" + self.get_classname() permission = self.get_modulename() + ".delete_" + self.get_classname()
can = user_request.has_perm(permission) can = user_request.has_perm(permission)
return ( return (
@ -147,10 +168,15 @@ class AclMixin(object):
@classmethod @classmethod
def can_view_all(cls, user_request, *_args, **_kwargs): def can_view_all(cls, user_request, *_args, **_kwargs):
"""Vérifie qu'on peut bien afficher l'ensemble des objets, """Check if a user can view all instances of an object
droit particulier view objet correspondant
:param user_request: instance user qui fait l'edition Parameters:
:return: True ou False avec la raison de l'échec le cas échéant""" user_request: User calling for this action
Returns:
Boolean: True if user_request has the right access to do it, else
false with reason for reject authorization
"""
permission = cls.get_modulename() + ".view_" + cls.get_classname() permission = cls.get_modulename() + ".view_" + cls.get_classname()
can = user_request.has_perm(permission) can = user_request.has_perm(permission)
return ( return (
@ -162,11 +188,16 @@ class AclMixin(object):
) )
def can_view(self, user_request, *_args, **_kwargs): def can_view(self, user_request, *_args, **_kwargs):
"""Vérifie qu'on peut bien voir cette instance particulière avec """Check if a user can view an instance of an object
droit view objet
:param self: instance à voir Parameters:
:param user_request: instance user qui fait l'edition user_request: User calling for this action
:return: True ou False avec la raison de l'échec le cas échéant""" self: Instance to view
Returns:
Boolean: True if user_request has the right access to do it, else
false with reason for reject authorization
"""
permission = self.get_modulename() + ".view_" + self.get_classname() permission = self.get_modulename() + ".view_" + self.get_classname()
can = user_request.has_perm(permission) can = user_request.has_perm(permission)
return ( return (

View file

@ -47,7 +47,15 @@ application = get_wsgi_application()
def get_user(pseudo): def get_user(pseudo):
"""Cherche un utilisateur re2o à partir de son pseudo""" """Find a user from its pseudo
Parameters:
pseudo (string): pseudo of this user
Returns:
user instance:Instance of user
"""
user = User.objects.filter(pseudo=pseudo) user = User.objects.filter(pseudo=pseudo)
if len(user) == 0: if len(user) == 0:
raise CommandError("Invalid user.") raise CommandError("Invalid user.")
@ -59,17 +67,20 @@ def get_user(pseudo):
def get_system_user(): def get_system_user():
"""Retourne l'utilisateur système ayant lancé la commande""" """Find the system user login who used the command
"""
return pwd.getpwuid(int(os.getenv("SUDO_UID") or os.getuid())).pw_name return pwd.getpwuid(int(os.getenv("SUDO_UID") or os.getuid())).pw_name
def form_cli(Form, user, action, *args, **kwargs): def form_cli(Form, user, action, *args, **kwargs):
""" """
Remplit un formulaire à partir de la ligne de commande Fill-in a django form from cli
Form : le formulaire (sous forme de classe) à remplir
user : l'utilisateur re2o faisant la modification Parameters
action : l'action réalisée par le formulaire (pour les logs) Form : a django class form to fill-in
Les arguments suivants sont transmis tels quels au formulaire. user : a re2o user doign the modification
action: the action done with that form, for logs purpose
""" """
data = {} data = {}
dumb_form = Form(user=user, *args, **kwargs) dumb_form = Form(user=user, *args, **kwargs)

View file

@ -24,12 +24,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# David Sinquin, Gabriel Détraz, Lara Kermarec # David Sinquin, Gabriel Détraz, Lara Kermarec
""" """
Regroupe les fonctions transversales utiles A group of very usefull functions for re2o core
Fonction : Functions:
- récupérer tous les utilisateurs actifs - find all active users
- récupérer toutes les machines - find all active interfaces
- récupérer tous les bans - find all bans
etc etc
""" """
@ -47,7 +47,14 @@ from preferences.models import AssoOption
def get_group_having_permission(*permission_name): def get_group_having_permission(*permission_name):
"""Returns every group having the permission `permission_name` """Return all django groups having this permission
Parameters:
permission name (string): Permission name
Returns:
re2o groups: Groups having this permission
""" """
groups = set() groups = set()
for name in permission_name: for name in permission_name:
@ -60,10 +67,19 @@ def get_group_having_permission(*permission_name):
def all_adherent(search_time=None, including_asso=True): def all_adherent(search_time=None, including_asso=True):
""" Fonction renvoyant tous les users adherents. Optimisee pour n'est """Return all people who have a valid membership at org. Optimised to make only one
qu'une seule requete sql sql query. Build a filter and then apply it to User. Check for each user if a valid
Inspecte les factures de l'user et ses cotisation, regarde si elles membership is registered at the desired search_time.
sont posterieur à now (end_time)"""
Parameters:
search_time (django datetime): Datetime to perform this search,
if not provided, search_time will be set à timezone.now()
including_asso (boolean): Decide if org itself is included in results
Returns:
django queryset: Django queryset containing all users with valid membership
"""
if search_time is None: if search_time is None:
search_time = timezone.now() search_time = timezone.now()
filter_user = Q( filter_user = Q(
@ -86,7 +102,18 @@ def all_adherent(search_time=None, including_asso=True):
def all_baned(search_time=None): def all_baned(search_time=None):
""" Fonction renvoyant tous les users bannis """ """Return all people who are banned at org. Optimised to make only one
sql query. Build a filter and then apply it to User. Check for each user
banned at the desired search_time.
Parameters:
search_time (django datetime): Datetime to perform this search,
if not provided, search_time will be set à timezone.now()
Returns:
django queryset: Django queryset containing all users banned
"""
if search_time is None: if search_time is None:
search_time = timezone.now() search_time = timezone.now()
return User.objects.filter( return User.objects.filter(
@ -97,7 +124,18 @@ def all_baned(search_time=None):
def all_whitelisted(search_time=None): def all_whitelisted(search_time=None):
""" Fonction renvoyant tous les users whitelistes """ """Return all people who have a free access at org. Optimised to make only one
sql query. Build a filter and then apply it to User. Check for each user with a
whitelisted free access at the desired search_time.
Parameters:
search_time (django datetime): Datetime to perform this search,
if not provided, search_time will be set à timezone.now()
Returns:
django queryset: Django queryset containing all users whitelisted
"""
if search_time is None: if search_time is None:
search_time = timezone.now() search_time = timezone.now()
return User.objects.filter( return User.objects.filter(
@ -108,11 +146,19 @@ def all_whitelisted(search_time=None):
def all_has_access(search_time=None, including_asso=True): def all_has_access(search_time=None, including_asso=True):
""" Return all connected users : active users and whitelisted + """Return all people who have an valid internet access at org. Optimised to make
asso_user defined in AssoOption pannel only one sql query. Build a filter and then apply it to User. Return users
---- with a whitelist, or a valid paid access, except banned users.
Renvoie tous les users beneficiant d'une connexion
: user adherent et whiteliste non banni plus l'utilisateur asso""" Parameters:
search_time (django datetime): Datetime to perform this search,
if not provided, search_time will be set à timezone.now()
including_asso (boolean): Decide if org itself is included in results
Returns:
django queryset: Django queryset containing all valid connection users
"""
if search_time is None: if search_time is None:
search_time = timezone.now() search_time = timezone.now()
filter_user = ( filter_user = (
@ -153,7 +199,20 @@ def all_has_access(search_time=None, including_asso=True):
def filter_active_interfaces(interface_set): def filter_active_interfaces(interface_set):
"""Filtre les machines autorisées à sortir sur internet dans une requête""" """Return a filter for filtering all interfaces of people who have an valid
internet access at org.
Call all_active_interfaces and then apply filter of theses active users on an
interfaces_set
Parameters:
interface_set (django queryset): A queryset of interfaces to perform filter
Returns:
django filter: Django filter to apply to an interfaces queryset,
will return when applied all active interfaces, related with
a user with valid membership
"""
return ( return (
interface_set.filter( interface_set.filter(
machine__in=Machine.objects.filter(user__in=all_has_access()).filter( machine__in=Machine.objects.filter(user__in=all_has_access()).filter(
@ -171,12 +230,38 @@ def filter_active_interfaces(interface_set):
def filter_complete_interfaces(interface_set): def filter_complete_interfaces(interface_set):
"""Appel la fonction précédente avec un prefetch_related ipv6 en plus""" """Return a filter for filtering all interfaces of people who have an valid
internet access at org.
Call all_active_interfaces and then apply filter of theses active users on an
interfaces_set. Less efficient than filter_active_interfaces, with a prefetch_related
on ipv6
Parameters:
interface_set (django queryset): A queryset of interfaces to perform filter
Returns:
django filter: Django filter to apply to an interfaces queryset,
will return when applied all active interfaces, related with
a user with valid membership
"""
return filter_active_interfaces(interface_set).prefetch_related("ipv6list") return filter_active_interfaces(interface_set).prefetch_related("ipv6list")
def all_active_interfaces(full=False): def all_active_interfaces(full=False):
"""Renvoie l'ensemble des machines autorisées à sortir sur internet """ """Return a filter for filtering all interfaces of people who have an valid
internet access at org.
Call filter_active_interfaces or filter_complete_interfaces.
Parameters:
full (boolean): A queryset of interfaces to perform filter. If true, will perform
a complete filter with filter_complete_interfaces
Returns:
django queryset: Django queryset containing all active interfaces, related with
a user with valid membership
"""
if full: if full:
return filter_complete_interfaces(Interface.objects) return filter_complete_interfaces(Interface.objects)
else: else:
@ -184,13 +269,30 @@ def all_active_interfaces(full=False):
def all_active_assigned_interfaces(full=False): def all_active_assigned_interfaces(full=False):
""" Renvoie l'ensemble des machines qui ont une ipv4 assignées et """Return all interfaces of people who have an valid internet access at org,
disposant de l'accès internet""" and with valid ipv4.
Call filter_active_interfaces or filter_complete_interfaces, with parameter full.
Parameters:
full (boolean): A queryset of interfaces to perform filter. If true, will perform
a complete filter with filter_complete_interfaces
Returns:
django queryset: Django queryset containing all active interfaces, related with
a user with valid membership, and with valid assigned ipv4 address
"""
return all_active_interfaces(full=full).filter(ipv4__isnull=False) return all_active_interfaces(full=full).filter(ipv4__isnull=False)
def all_active_interfaces_count(): def all_active_interfaces_count():
""" Version light seulement pour compter""" """Counts all interfaces of people who have an valid internet access at org.
Returns:
int: Number of all active interfaces, related with
a user with valid membership.
"""
return Interface.objects.filter( return Interface.objects.filter(
machine__in=Machine.objects.filter(user__in=all_has_access()).filter( machine__in=Machine.objects.filter(user__in=all_has_access()).filter(
active=True active=True
@ -199,12 +301,26 @@ def all_active_interfaces_count():
def all_active_assigned_interfaces_count(): def all_active_assigned_interfaces_count():
""" Version light seulement pour compter""" """Counts all interfaces of people who have an valid internet access at org,
and with valid ipv4.
Returns:
int: Number of all active interfaces, related with
a user with valid membership, and with valid assigned ipv4 address
"""
return all_active_interfaces_count().filter(ipv4__isnull=False) return all_active_interfaces_count().filter(ipv4__isnull=False)
def remove_user_room(room, force=True): def remove_user_room(room, force=True):
""" Déménage de force l'ancien locataire de la chambre """ """Remove the previous user of that room. If force, will not perform a check
of membership on him before doing it
Parameters:
room (Room instance): Room to make free of user
force (boolean): If true, bypass membership check
"""
try: try:
user = Adherent.objects.get(room=room) user = Adherent.objects.get(room=room)
except Adherent.DoesNotExist: except Adherent.DoesNotExist:

View file

@ -21,8 +21,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., # with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
""" """
Fonctions de la page d'accueil et diverses fonctions utiles pour tous Welcom main page view, and several template widely used in re2o views
les views
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
@ -50,14 +49,29 @@ from re2o.settings_local import OPTIONNAL_APPS_RE2O
def form(ctx, template, request): def form(ctx, template, request):
"""Form générique, raccourci importé par les fonctions views du site""" """Global template function, used in all re2o views, for building a render with context,
template and request. Adding csrf.
Parameters:
ctx (dict): Dict of values to transfer to template
template (django template): The django template of this view
request (django request)
Returns:
Django render: Django render complete view with template, context and request
"""
context = ctx context = ctx
context.update(csrf(request)) context.update(csrf(request))
return render(request, template, context) return render(request, template, context)
def index(request): def index(request):
"""Affiche la liste des services sur la page d'accueil de re2o""" """Display all services provided on main page
Returns: a form with all services linked and description, and social media
link if provided.
"""
services = [[], [], []] services = [[], [], []]
for indice, serv in enumerate(Service.objects.all()): for indice, serv in enumerate(Service.objects.all()):
services[indice % 3].append(serv) services[indice % 3].append(serv)