async def resend_receipt(request, response, siren, year): try: record = await db.declaration.get(siren, year) except db.NoData: raise HttpError(404, f"No declaration with siren {siren} and year {year}") owners = await db.ownership.emails(siren) data = record.data url = request.domain + data.uri emails.success.send(owners, url=url, **data) response.status = 204
async def essay(request: Request, response: CustomResponse, parameter: str) -> None: template_name = "essay.html" template = language_aware_template(template_name, request["language"]) try: md_content = get_md_content_from_disk(parameter) except FileNotFoundError: raise HttpError(HTTPStatus.NOT_FOUND, "Essay not found.") content = commonmark(md_content) content = escape_content(content, allowed_tags=ALLOWED_TAGS) response.html(template, content=content)
def json(self): data = super().json if not isinstance(data, dict): raise HttpError(400, "`data` doit être de type objet JSON") id_ = data.get("id") if "data" in data: data = data["data"] # Legacy identifier, be defensive and try hard to find it. if "id" not in data and id_: data["id"] = id_ return data
async def on_put(self, request, response, uuid): data = request.json if not isinstance(data, dict): raise HttpError(400, "JSON invalide") await db.simulation.put(uuid, data) record = await db.simulation.get(uuid) response.json = record.as_resource() response.status = 200 draft = data.get("declaration", {}).get("formValidated") != "Valid" email = data.get("informationsDeclarant", {}).get("email") if email and not draft: token = tokens.create(email) response.cookies.set(name="api-key", value=token)
async def wrapper(request, response, siren, *args, **kwargs): declarant = request["email"] owners = await db.ownership.emails(siren) if declarant in owners: request["is_owner"] = True # Allow to create a declaration for a siren without any owner yet. elif owners: loggers.logger.debug( "Non owner (%s) accessing owned resource %s %s", declarant, siren, args ) if not request["staff"]: msg = f"Vous n'avez pas les droits nécessaires pour le siren {siren}" raise HttpError(403, msg) return await view(request, response, siren, *args, **kwargs)
async def send_token(request, response): # TODO mailbomb management in nginx email = request.json.get("email") if not email: raise HttpError(400, "Missing email key") token = tokens.create(email) link = f"{request.domain}/declaration/?token={token}" if "localhost" in link or "127.0.0.1" in link: print(link) loggers.logger.info(f"Token request FOR {email} FROM {request.ip}") if request.ip in config.ALLOWED_IPS: response.json = {"token": token} else: body = emails.ACCESS_GRANTED.format(link=link) emails.send(email, "Déclarer sur Egapro", body) response.status = 204
async def on_post(self, request, response): payload = request.json try: kind = payload["kind"] page = payload["page"] message = payload["message"] except KeyError: raise HttpError(HTTPStatus.BAD_REQUEST) message = f"{self.KIND_EMOJI[kind]} ({page}): {message}" user_agent = request.headers.get("USER-AGENT") if user_agent: message += f" [envoyé depuis {parse(user_agent)}]" if request.host.startswith("127.0.0.1"): print(message) else: await request.app.bot.send_message(message) response.status = HTTPStatus.ACCEPTED response.json = {"message": message}
async def remuneration_(request, response): data = request.json remunerations = get_remunerations(tags=request.query.list("tags", [])) try: flatten(data) context = Context(data.copy()) routine.extrapolate_context(context) routine.preprocess(context) for remuneration in remunerations: copy = context.copy() routine.check_remuneration(context, remuneration) data.update(copy.cleaned_data) # FIXME (limits of the single-store-all context object) # Clean keys not meant to be exposed for key in list(data.keys()): if key.startswith("remuneration"): del data[key] except DataError as err: error = {err.key: err.error} log_simulate(context, errors=error) raise HttpError(HTTPStatus.UNPROCESSABLE_ENTITY, error) # TODO: explain only for financement see routine.py check_remuneration # explain = request.query.bool("explain", False) # for remuneration in remunerations: # remuneration["explain"] = ( # [s.json for s in remunerations["explain"]] if explain else None # ) body = {"remunerations": remunerations} # if request.query.bool("context", False): # body["context"] = { # k: v for k, v in context.items() # if k in SCHEMA and "label" in SCHEMA[k]} response.json = body """
async def remuneration_(request, response): context = request.json remunerations = get_remunerations(tags=request.query.list("tags", [])) try: await simulate_remuneration(context, remunerations) except DataError as err: error = {err.key: err.error} log_simulate(request, response, context, errors=error) raise HttpError(HTTPStatus.BAR_REQUEST, error) # TODO: explain only for financement see routine.py check_remuneration # explain = request.query.bool("explain", False) # for remuneration in remunerations: # remuneration["explain"] = ( # [s.json for s in remunerations["explain"]] if explain else None # ) body = {"remunerations": remunerations} # if request.query.bool("context", False): # body["context"] = { # k: v for k, v in context.items() # if k in SCHEMA and "label" in SCHEMA[k]} response.json = body
async def validate_siren(request, response): siren = request.query.get("siren") if not siren_is_valid(siren): raise HttpError(422, f"Numéro SIREN invalide: {siren}") metadata = await helpers.load_from_api_entreprises(siren) response.json = metadata
async def get(req, resp): raise HttpError(500, 'Oops.')
async def delete_owner(request, response, siren, email): owners = await db.ownership.emails(siren) if len(owners) == 1: raise HttpError(403, "Impossible de supprimer le dernier propriétaire.") await db.ownership.delete(siren, email) response.status = 204
async def put_owner(request, response, siren, email): if "is_owner" not in request: raise HttpError(403, "Vous n'avez pas les droits nécessaires") await db.ownership.put(siren, email) response.status = 204
async def get(req, resp): raise HttpError(HTTPStatus.INTERNAL_SERVER_ERROR)
async def get(req, resp): raise HttpError(500)
async def get(req, resp): raise HttpError(HTTPStatus.BAD_REQUEST, 'Really bad.')
async def simulate_legacy(request, response): context = request.json context["individu"]["departementHabitation"] = context["individu"][ "departementHabitation" ].upper() financements = get_financements(tags=request.query.list("tags", [])) try: await simulate(context, financements) except DataError as err: error = {err.key: err.error} log_simulate(context, errors=error) raise HttpError(HTTPStatus.BAD_REQUEST, error) financements = [f for f in financements if f["eligible"]] log_simulate(context, financements=financements) mapped = [] for financement in financements: for tag, label in FAMILLE_MAPPING.items(): if tag in financement.tags: famille = label break else: famille = "Formation / emploi" # codes financeur actually retrieve from ad codes_financeur = context["formation.codes_financeur"] or [] if financement.type_lbf == "aif" and context.get( "formation.bilan_de_competences" ): financement.type_lbf = "aifbilancompetence" if financement.type_lbf == "aif" and context.get("formation.permis_b"): financement.type_lbf = "finindividuelpermisb" if ( financement.type_lbf == "afprpoei" and context.get("beneficiaire.departement") == "971" ): financement.type_lbf = "poei" data = { "libelle": financement.intitule, "donneeConsolidees": { "description": financement.demarches, "infoComplementaires": financement.description, "cout": financement.prise_en_charge_texte, "remuneration": financement.remuneration_texte, }, "donneeStructurees": { "familleDispositif": famille, "typeDispositif": financement.type_lbf, "priorite": financement.priorite_lbf, "codesFinanceur": list(map(str, codes_financeur)), "cout": { "resteACharge": "partiellement" in financement.prise_en_charge_texte, # TODO see in PHP code logic to determine this bool value "financeePE": financement.financee_pe, "financableCpf": financement.cpf_mobilisable, "cumulable": financement.cumulable, # TODO voir avec Armelle pour fixer cette valeur dans financement.yml }, }, } if financement.remuneration: data["donneeStructurees"]["remunerations"] = [ {"montant": financement.remuneration, "nature": "brut"} ] if ( financement.type_lbf == "cpf" and context.get("beneficiaire.solde_cpf") ): data["donneeStructurees"]["cout"]["montant"] = "%.2f" % ( context.get("beneficiaire.solde_cpf") ) elif financement.get("plafond_prise_en_charge") not in [0, None]: if financement.type_lbf == "aifartisan": data["donneeStructurees"]["cout"]["montant"] = "%.2f" % financement.get( "plafond_prise_en_charge" ) elif financement.type_lbf != "cpf": data["donneeStructurees"]["cout"]["plafond"] = "%.2f" % financement.get( "plafond_prise_en_charge" ) if not financement.remuneration_texte: if financement.remuneration: financement.remuneration_texte = ( f"Vous percevrez {financement.remuneration} € brut / mois" ) else: financement.remuneration_texte = f"Pas de rémunération spécifique" mapped.append(data) response.json = {"financements": mapped}
async def get(req, resp): raise HttpError(HTTPStatus.INTERNAL_SERVER_ERROR, message='JSON error')