def get_demande_types_for_user(user: Profile) -> set[str]: role_service = injector.get(RoleService) contact_service = injector.get(ContactService) roles = role_service.get_roles_for_user(user) structures = roles.get(Role.PORTEUR, set()) | roles.get( Role.GESTIONNAIRE, set()) # Cf. https://trello.com/c/UM96aY5s result = {"faq"} for s in structures: if not contact_service.get_mapping_for(s): continue if role_service.has_role(user, Role.PORTEUR, s): result |= {"autre"} x = MAP[s.type] if REC in x: result |= {"rh"} if PI in x: result |= {"pi_invention", "pi_logiciel"} if CON in x: result |= {"convention", "avenant_convention"} return result
def _get_stakeholders(self, workflow: Workflow) -> Container: from flask_sqlalchemy import SQLAlchemy from labster.di import injector from labster.domain2.model.profile import Profile db = injector.get(SQLAlchemy) demande: Demande = workflow.case stakeholders = set(demande.owners) if demande.contact_labco: stakeholders.add(demande.contact_labco) # FIXME # structure: Structure = demande.structure # directeurs = structure.get_directeurs() # for directeur in directeurs: # stakeholders.add(directeur) for history_item in demande.wf_history: actor_id = history_item["actor_id"] if actor_id: # TODO if isinstance(actor_id, int): actor = db.session.query(Profile).filter_by( old_id=actor_id).first() else: actor = db.session.query(Profile).get(actor_id) if actor: stakeholders.add(actor) return stakeholders
def get_demandes_for(self, user: Profile): role_service = injector.get(RoleService) roles = role_service.get_roles_for_user(user) structures = set(roles[Role.GESTIONNAIRE]) | set( roles[Role.RESPONSABLE]) for s in set(structures): structures |= s.descendants structure_ids = {s.id for s in structures} toutes_les_demandes = (base_query().filter_by( active=(not self.archives)).order_by( Demande.created_at.desc()).all()) result = [] for demande in toutes_les_demandes: if demande.structure_id in structure_ids: result.append(demande) continue for d in demande.data.get("structures_concernees", []): structure_id = d["value"] if structure_id in structure_ids: result.append(demande) return result
def _get_users_with_role(self, role: Role) -> set[Profile]: from labster.di import injector from labster.domain2.services.roles import RoleService role_service = injector.get(RoleService) responsables = role_service.get_users_with_given_role(role, self) return responsables
def wf_transition(demande_id, action, data=None): data = data or {} user = get_current_profile() db = injector.get(SQLAlchemy) demande = db.session.query(Demande).get(demande_id) workflow = demande.get_workflow(user) try: transition = workflow.get_transition_by_id(action) except IndexError: msg = ( "Action impossible. Quelqu'un a probablement effectué une action " "sur la demande en parallèle avec vous.", "danger", ) return msg workflow.execute_transition(transition, data=data) db.session.commit() msg = ( f"Votre action '{transition.label}' sur la demande '{demande.nom}' a bien été prise en compte.", "success", ) return msg
def dump_structures(): structure_repo = injector.get(StructureRepository) structures = structure_repo.get_all() for s in structures: print(s.nom) print("Children:", s.children) print("Parents:", s.parents) print()
def is_membre_dri(self): from labster.di import injector from labster.domain2.model.structure import StructureRepository from labster.domain2.services.roles import Role structure_repo = injector.get(StructureRepository) dri = structure_repo.get_by_dn(DRI_DN) return self.has_role(Role.MEMBRE, dri)
def base_query(): db = injector.get(SQLAlchemy) return db.session.query(Demande).options( joinedload(Demande.structure), joinedload(Demande.contact_labco), joinedload(Demande.gestionnaire), joinedload(Demande.porteur), )
def structure_d_appartenance(self) -> Structure: from labster.di import injector from labster.domain2.services.roles import Role, RoleService role_service = injector.get(RoleService) roles_dict = role_service.get_roles_for_user(self) structures = roles_dict[Role.MEMBRE_AFFECTE] assert len(structures) == 1 return list(structures)[0]
def acces_restreint(demande: Demande) -> bool: """Retourne True si l'utilisateur courant n'a pas le droit de voir les info confidentielles d'un formulaire RH.""" if not isinstance(demande, DemandeRH): return False user = get_current_profile() if user in {demande.porteur, demande.gestionnaire, demande.contact_labco}: return False if user.has_role(Role.ADMIN_CENTRAL): return False # Les responsables "ascendants" ne voient pas le détail # sauf pour les structures "concernées". # NB: le labo est toujours "concerné" if demande.structure: if user.has_role(Role.RESPONSABLE, demande.structure): return False dri = structure_repo.get_by_dn(DRI_DN) if user.has_role(Role.RESPONSABLE, dri): return False structures = demande.get_structure_concernees() for structure in structures: if user.has_role(Role.RESPONSABLE, structure): return False # Responsable facultaire et admin facultaire if demande.structure: structures.add(demande.structure) for structure in structures: ancestors = structure.ancestors for ancestor in ancestors: if ancestor.type != FA: continue if user.has_role(Role.RESPONSABLE, ancestor): return False # Admin facultaire for sous_structure in ancestor.children: if sous_structure.sigle.startswith("DRV "): if user.has_role(Role.ADMIN_LOCAL, sous_structure): return False contact_service = injector.get(ContactService) mapping = contact_service.get_mapping() for d in mapping.values(): if d.get(ContactType.CONTACT_RH) == user: return False return True
def backdoor(login="******"): app = injector.get(Flask) if not (app.config.get("ALLOW_BACKDOOR") or app.testing): raise Unauthorized() user = get_user_by_login(login) login_user(user) return None
def get_membres(structure): """Retourne les membres (affectés et rattachés) et de la sous-structure (sans les membres affiliés).""" role_service = injector.get(RoleService) m1 = role_service.get_users_with_given_role(Role.MEMBRE_AFFECTE, structure) m2 = role_service.get_users_with_given_role(Role.MEMBRE_RATTACHE, structure) membres = list(set(m1) | set(m2)) membres = sort_by_name(membres) membres = [m for m in membres if m.active] return membres
def get_structure_concernees(self): from labster.di import injector structure_repo = injector.get(StructureRepository) result = set() if self.data.get("structures_concernees"): for d in self.structures_concernees: structure_id = d["value"] structure = structure_repo.get_by_id(structure_id) if structure: result.add(structure) return result
def can_view_stats(): auth_context = injector.get(AuthContext) user = auth_context.current_profile # For tests if not user: return True if user.has_role(Role.RESPONSABLE, "*"): return True if user.has_role(Role.ADMIN_CENTRAL): return True return False
def login_user(): current_user_id = session.get("current_user_id", "ANONYMOUS") logger = structlog.get_logger() if current_user_id == "ANONYMOUS": g.current_user = AnonymousUser() g.current_profile = None logger.new(user=None) else: try: profile_repos = injector.get(ProfileRepository) profile = profile_repos.get_by_id(current_user_id) g.current_profile = profile g.current_user = AuthenticatedUser(profile) except: g.current_user = AnonymousUser() g.current_profile = None logger.new(user=g.current_user.name)
from labster.di import injector from labster.domain2.model.demande import Demande, DemandeRH from labster.domain2.model.profile import Profile from labster.domain2.services.roles import Role, RoleService from labster.infrastructure.repositories.sqla.mappers import Mapper from labster.newforms import get_form_class_by_name, get_form_class_for from labster.rbac import acces_restreint, can_duplicate, check_read_access, \ feuille_cout_editable, has_write_access from labster.rpc.registry import context_for from labster.rpc.util import owner_sorter from labster.security import get_current_profile from labster.types import JSON, JSONDict, JSONList logger = structlog.get_logger() mapper = injector.get(Mapper) db = injector.get(SQLAlchemy) role_service = injector.get(RoleService) @context_for("demande.new") @method def get_new(type: str = "calculette_rh") -> JSONDict: """Retourne les données nécessaires pour un formulaire vierge.""" calculette = False if type == "calculette_rh": calculette = True type = "rh" form_class = get_form_class_by_name(type) form = form_class(mode="create") form.update_choices()
import json from typing import Any, Dict, List, Optional, Set, Tuple from werkzeug.exceptions import NotFound from labster.di import injector from labster.domain2.model.profile import Profile, ProfileId, ProfileRepository from labster.domain2.model.structure import Structure, StructureRepository from labster.domain2.model.type_structure import DE, EQ from labster.domain2.services.contacts import ContactService from labster.domain2.services.roles import Role, RoleService from labster.rpc.registry import context_for from labster.types import JSON, JSONDict role_service = injector.get(RoleService) contact_service = injector.get(ContactService) profile_repo = injector.get(ProfileRepository) structure_repo = injector.get(StructureRepository) @context_for("user") def get_user(id: str) -> JSONDict: user = profile_repo.get_by_id(ProfileId(id)) if not user: user = profile_repo.get_by_old_uid(id) if not user: raise NotFound() structure_affectation_dto: JSON if user.affectation:
from labster.bi.synchro import sync_all from labster.blueprints.notifications.mails import send_notification_to, \ send_recap_to from labster.di import injector from labster.domain2.model.demande import Demande from labster.domain2.model.profile import DAILY, WEEKLY, Profile, \ ProfileRepository from labster.domain2.model.structure import StructureRepository from labster.domain2.services.roles import Role, RoleService from labster.ldap import sync from labster.rpc.cache import cache logger = structlog.get_logger() profile_repository = injector.get(ProfileRepository) db = injector.get(SQLAlchemy) role_service = injector.get(RoleService) # # Development commands # @click.command() @click.option("--server", default="flask") @click.option("--coverage") @with_appcontext def devserver(server, coverage=False): if server == "flask": if coverage: flask = shutil.which("flask")
def auth_context(): return injector.get(AuthContext)
def profile_repo(): return injector.get(ProfileRepository)
def __init__(self): self.profile_repo = injector.get(ProfileRepository) self.structure_repo = injector.get(StructureRepository) self.role_service = injector.get(RoleService)
import ramda as r from flask_sqlalchemy import SQLAlchemy from jsonrpcserver import method from marshmallow import Schema, fields from sqlalchemy import or_ from labster.di import injector from labster.domain2.model.profile import Profile from labster.domain2.model.structure import Structure from labster.domain2.services.roles import Role, RoleService from labster.rpc.cache import cache from labster.types import JSONDict from labster.util import sort_by_name db = injector.get(SQLAlchemy) role_service = injector.get(RoleService) @method @cache.memoize(tag="users", expire=3600) def get_users(q="", page=0) -> JSONDict: page = int(page) query = (db.session.query(Profile).filter(Profile.active == True).order_by( Profile.nom, Profile.prenom)) total = query.count() q = q.strip() if q: query = query.filter( or_(Profile.nom.ilike(f"{q}%"), Profile.prenom.ilike(f"{q}%")))
from __future__ import annotations from typing import Dict, List from flask_sqlalchemy import SQLAlchemy from jsonrpcserver import method from labster.di import injector from labster.domain2.model.profile import Profile, ProfileRepository from labster.domain2.model.structure import StructureRepository from labster.domain2.services.roles import Role, RoleService from labster.rpc.cache import cache structure_repo = injector.get(StructureRepository) profile_repo = injector.get(ProfileRepository) role_service = injector.get(RoleService) db = injector.get(SQLAlchemy) @method def update_membres_rattaches(structure_id: str, values: list[dict]): structure = structure_repo.get_by_id(structure_id) assert structure membres: list[Profile] = role_service.get_users_with_given_role( Role.MEMBRE_RATTACHE, structure) current_membre_ids = {m.id for m in membres} updated_membre_ids = {m["id"] for m in values} membres_to_add = updated_membre_ids.difference(current_membre_ids)
def get_mapping(): contact_service = injector.get(ContactService) return contact_service.get_mapping()
def structure_repo(): return injector.get(StructureRepository)
from __future__ import annotations from typing import Any, Dict, List from labster.di import injector from labster.domain2.model.profile import ProfileRepository from labster.domain2.services.roles import Role, RoleService from labster.security import get_current_profile from labster.util import url_for profile_repository = injector.get(ProfileRepository) role_service = injector.get(RoleService) class Node: _label = "" def __getitem__(self, key: str) -> Any: return getattr(self, "_" + key) def get(self, key: str, default=None) -> Any: return getattr(self, "_" + key, default) def is_active(self) -> bool: profile = get_current_profile() required_roles = self.get("requires_role") precondition = self.get("precondition") if precondition: return precondition()
def role_service(): return injector.get(RoleService)
"mes structures", ] SCOPES_RESPONSABLE = [ # DR&I "contact", "mes structures dri", "dri", "drv", # Autres structures "mes structures", "porteur", "gestionnaire", ] role_service = injector.get(RoleService) def get_boxes(archives=False) -> JSON: archives = bool(archives) user = get_current_profile() if role_service.has_role(user, Role.RESPONSABLE, "*"): scopes = SCOPES_RESPONSABLE else: scopes = SCOPES result = [] for scope in scopes: table_view = get_table_view(scope, user, archives) if table_view: result.append({
from __future__ import annotations from flask_sqlalchemy import SQLAlchemy from jsonrpcserver import method from werkzeug.exceptions import BadRequest from labster.di import injector from labster.domain2.services.constants import save_constants db = injector.get(SQLAlchemy) @method def update_constants(constants): if not constants: raise BadRequest() save_constants(constants) db.session.commit()
"""""" from __future__ import annotations from os.path import dirname from typing import Any, Dict from flask import render_template from flask_weasyprint import HTML from labster.di import injector from labster.domain2.model.demande import DemandeRH from labster.domain2.model.structure import StructureRepository from labster.domain2.services.calculs_couts import get_ctx_for_demande structure_repo = injector.get(StructureRepository) def devis_rh(demande: DemandeRH): ctx = get_ctx_for_demande(demande) ctx.update(additional_ctx_for_demande(demande)) ctx["css_rules"] = open( dirname(__file__) + "/../../static/print/devis.css").read() html = render_template("documents-generes/devis-rh.html", **ctx) pdf = HTML(string=html).write_pdf() return pdf def lettre_commande_rh(demande: DemandeRH): ctx = get_ctx_for_demande(demande) ctx.update(additional_ctx_for_demande(demande))