def releveHandler(request, *, releve, info_role): # Test des droits d'édition du relevé if releve.id_releve_occtax is not None: user_cruved = get_or_fetch_user_cruved(session=session, id_role=info_role.id_role, module_code="OCCTAX") # info_role.code_action = update_data_scope user = UserRigth( id_role=info_role.id_role, value_filter=user_cruved["U"], code_action="U", id_organisme=info_role.id_organisme, ) releve = releve.get_releve_if_allowed(user) # fin test, si ici => c'est ok # if creation else: if info_role.value_filter in ("0", "1", "2"): # Check if user can add a releve in the current dataset allowed = releve.user_is_in_dataset_actor(info_role) if not allowed: raise InsufficientRightsError( "User {} has no right in dataset {}".format( info_role.id_role, releve.id_dataset), 403, ) # creation du relevé à partir du POST releveSchema = ReleveSchema() # Modification de la requete geojson en releve json_req = request.get_json() json_req["properties"]["geom_4326"] = json_req["geometry"] # chargement des données POST et merge avec relevé initial releve, errors = releveSchema.load(json_req["properties"], instance=releve) if bool(errors): raise InsufficientRightsError( errors, 422, ) # set id_digitiser releve.id_digitiser = info_role.id_role DB.session.add(releve) DB.session.commit() DB.session.flush() return releve
def __check_cruved_scope(*args, **kwargs): user = get_user_from_token_and_raise(request, action, redirect_on_expiration, redirect_on_invalid_token) # If user not a dict: its a token issue # return the appropriate Response from get_user_from_token_and_raise if not isinstance(user, dict): return user user_with_highter_perm = None user_permissions = get_user_permissions(user, "SCOPE", action, module_code, object_code) user_cruved_obj = UserCruved() user_with_highter_perm = user_cruved_obj.build_herited_user_cruved( user_permissions, module_code, object_code) # if get_role = True : set info_role as kwargs if get_role: kwargs["info_role"] = user_with_highter_perm # if no perm or perm = 0 -> raise 403 if user_with_highter_perm is None or ( user_with_highter_perm is not None and user_with_highter_perm.value_filter == "0"): if object_code: message = f"""User {user_with_highter_perm.id_role} cannot "{user_with_highter_perm.code_action}" {object_code}""" else: message = f"""User {user_with_highter_perm.id_role}" cannot "{user_with_highter_perm.code_action}" in {user_with_highter_perm.module_code}""" raise InsufficientRightsError(message, 403) g.user = user_with_highter_perm return fn(*args, **kwargs)
def get_user_permissions(user, code_filter_type, code_action=None, module_code=None, code_object=None): """ Get all the permissions of a user for an action, a module (or an object) and a filter_type Users permissions could be multiples because of user's group. The view mapped by VUsersPermissions does not take the max because some filter type could be not quantitative Parameters: user(dict) code_filter_type(str): <SCOPE, GEOGRAPHIC ...> code_action(str): <C,R,U,V,E,D> or None if all actions wanted module_code(str): 'GEONATURE', 'OCCTAX' code_object(str): 'PERMISSIONS', 'DATASET' (table gn_permissions.t_oject) Return: Array<VUsersPermissions> """ user_cruved = UserCruved( id_role=user["id_role"], code_filter_type=code_filter_type, module_code=module_code, object_code=code_object, ).get_user_perm_list(code_action=code_action) object_for_error = None try: assert len(user_cruved) > 0 return user_cruved except AssertionError: object_for_error = ",".join(filter(None, (code_object, module_code))) raise InsufficientRightsError( f"User {user['id_role']} cannot '{code_action}' in module/app/object {object_for_error}" )
def datasetHandler(request, *, dataset, info_role): # Test des droits d'édition du dataset si modification if dataset.id_dataset is not None: user_cruved = cruved_scope_for_user_in_module( id_role=info_role.id_role, module_code="METADATA", )[0] dataset_cruved = dataset.get_object_cruved(info_role, user_cruved) #verification des droits d'édition pour le dataset if not dataset_cruved['U']: raise InsufficientRightsError( "User {} has no right in dataset {}".format( info_role.id_role, dataset.id_dataset), 403, ) else: dataset.id_digitizer = info_role.id_role datasetSchema = DatasetSchema() dataset, errors = datasetSchema.load(request.get_json(), instance=dataset) if bool(errors): log.error(errors) raise BadRequest(errors) DB.session.add(dataset) DB.session.commit() return dataset
def post_dataset(info_role): """ Post a dataset .. :quickref: Metadata; """ if info_role.value_filter == "0": raise InsufficientRightsError( ('User "{}" cannot "{}" a dataset').format(info_role.id_role, info_role.code_action), 403, ) data = dict(request.get_json()) cor_dataset_actor = data.pop("cor_dataset_actor") modules = data.pop("modules") dataset = TDatasets(**data) for cor in cor_dataset_actor: # remove id_cda if None otherwise merge no working well if "id_cda" in cor and cor["id_cda"] is None: cor.pop("id_cda") dataset.cor_dataset_actor.append(CorDatasetActor(**cor)) # init the relationship as an empty list modules_obj = (DB.session.query(TModules).filter( TModules.id_module.in_(modules)).all()) dataset.modules = modules_obj if dataset.id_dataset: DB.session.merge(dataset) else: DB.session.add(dataset) DB.session.commit() return dataset.as_dict(True)
def __check_cruved_scope(*args, **kwargs): user = get_user_from_token_and_raise(request, action, redirect_on_expiration, redirect_on_invalid_token) user_with_highter_perm = None user_with_highter_perm = UserCruved( id_role=user["id_role"], code_filter_type="SCOPE", module_code=module_code, object_code=object_code, ).get_herited_user_cruved_by_action(action) if user_with_highter_perm: user_with_highter_perm = user_with_highter_perm[0] # if get_role = True : set info_role as kwargs if get_role: kwargs["info_role"] = user_with_highter_perm # if no perm or perm = 0 -> raise 403 if user_with_highter_perm is None or ( user_with_highter_perm is not None and user_with_highter_perm.value_filter == "0"): if object_code: message = f"""User {user["id_role"]} cannot "{action}" {object_code}""" else: message = f"""User {user["id_role"]}" cannot "{action}" in {module_code}""" raise InsufficientRightsError(message, 403) g.user = user_with_highter_perm return fn(*args, **kwargs)
def post_dataset(info_role): if info_role.value_filter == "0": raise InsufficientRightsError( ('User "{}" cannot "{}" a dataset').format( info_role.id_role, info_role.code_action ), 403, ) data = dict(request.get_json()) cor_dataset_actor = data.pop("cor_dataset_actor") dataset = TDatasets(**data) for cor in cor_dataset_actor: # remove id_cda if None otherwise merge no working well if "id_cda" in cor and cor["id_cda"] is None: cor.pop("id_cda") dataset.cor_dataset_actor.append(CorDatasetActor(**cor)) if dataset.id_dataset: DB.session.merge(dataset) else: DB.session.add(dataset) DB.session.commit() return dataset.as_dict(True)
def acquisitionFrameworkHandler(request, *, acquisition_framework, info_role): # Test des droits d'édition du acquisition framework si modification if acquisition_framework.id_acquisition_framework is not None: user_cruved = cruved_scope_for_user_in_module( id_role=info_role.id_role, module_code="METADATA", )[0] af_cruved = acquisition_framework.get_object_cruved( info_role, user_cruved) #verification des droits d'édition pour le acquisition framework if not af_cruved['U']: raise InsufficientRightsError( "User {} has no right in acquisition_framework {}".format( info_role.id_role, acquisition_framework.id_acquisition_framework), 403, ) else: acquisition_framework.id_digitizer = info_role.id_role acquisitionFrameworkSchema = AcquisitionFrameworkSchema() acquisition_framework, errors = acquisitionFrameworkSchema.load( request.get_json(), instance=acquisition_framework) if bool(errors): raise BadRequest(errors) DB.session.add(acquisition_framework) DB.session.commit() return acquisition_framework
def delete_mapping(info_role, id_mapping): """ Delete a mappping In order to delete temporary mapping (which are automaticaly created) we don't check 'Delete' rights on 'mapping' object. Any user which is user of a mapping can delete it with this route """ data = ( DB.session.query(CorRoleMapping.id_mapping) .filter(CorRoleMapping.id_role == info_role.id_role) .all() ) users_mappings = [d.id_mapping for d in data] if id_mapping not in users_mappings: raise InsufficientRightsError( ('User "{}" cannot delete this mapping').format(info_role.id_role), ) else: mapping = DB.session.query(TMappings).get(id_mapping) # delete the mapping itself DB.session.delete(mapping) DB.session.commit() return mapping.as_dict()
def acquisitionFrameworkHandler(request, *, acquisition_framework, info_role): # Test des droits d'édition du acquisition framework si modification if acquisition_framework.id_acquisition_framework is not None: user_cruved = get_scopes_by_action(module_code="META_DATA") #verification des droits d'édition pour le acquisition framework if not acquisition_framework.has_instance_permission(user_cruved['U']): raise InsufficientRightsError( "User {} has no right in acquisition_framework {}".format( g.current_user, acquisition_framework.id_acquisition_framework), 403, ) else: acquisition_framework.id_digitizer = info_role.id_role acquisitionFrameworkSchema = AcquisitionFrameworkSchema(only=[ "cor_af_actor", "cor_volets_sinp", "cor_objectifs", "cor_territories" ], unknown=EXCLUDE) try: acquisition_framework = acquisitionFrameworkSchema.load( request.get_json(), instance=acquisition_framework) except ValidationError as error: log.exception(error) raise BadRequest(error.messages) DB.session.add(acquisition_framework) DB.session.commit() return acquisition_framework
def __check_cruved_scope(*args, **kwargs): user = get_user_from_token_and_raise(request, action, redirect_on_expiration, redirect_on_invalid_token) # If user not a dict: its a token issue # return the appropriate Response from get_user_from_token_and_raise if not isinstance(user, dict): return user user_with_highter_perm = None user_permissions = get_user_permissions(user, action, "SCOPE", module_code, object_code) # if object_code no heritage if object_code: user_with_highter_perm = get_max_perm(user_permissions) else: # else # loop on user permissions # return the module permission if exist # otherwise return GEONATURE permission module_permissions = [] geonature_permission = [] # filter the GeoNature perm and the module perm in two # arrays to make heritage for user_permission in user_permissions: if user_permission.module_code == module_code: module_permissions.append(user_permission) else: geonature_permission.append(user_permission) # take the max of the different permissions # if no module permission take the max of GN perm if len(module_permissions) == 0: user_with_highter_perm = get_max_perm(geonature_permission) # if at least one module perm: take the max of module perms else: user_with_highter_perm = get_max_perm(module_permissions) # if get_role = True : set info_role as kwargs if get_role: kwargs["info_role"] = user_with_highter_perm # if no perm or perm = 0 -> raise 403 if user_with_highter_perm is None or ( user_with_highter_perm is not None and user_with_highter_perm.value_filter == "0"): raise InsufficientRightsError( ('User "{}" cannot "{}" in {}').format( user_with_highter_perm.id_role, user_with_highter_perm.code_action, user_with_highter_perm.module_code, ), 403, ) g.user = user_with_highter_perm return fn(*args, **kwargs)
def get_observation_if_allowed(self, user, user_datasets): """ Return the observation if the user is allowed params: user: object from TRole """ if self.user_is_allowed_to(user, user.value_filter, user_datasets): return self raise InsufficientRightsError( ('User "{}" cannot "{}" this current releve').format(user.id_role, user.code_action), 403, )
def check_user_cruved_visit(user, visit, cruved_level): """ Check if user have right on a visit object, related to his cruved if not, raise 403 error if allowed return void """ is_allowed = False if cruved_level == '1': for role in visit.observers: if role.id_role == user.id_role: print('même id ') is_allowed = True break elif visit.id_digitiser == user.id_role: is_allowed = True break if not is_allowed: raise InsufficientRightsError( ('User "{}" cannot update visit number {} ').format( user.id_role, visit.id_base_visit), 403) elif cruved_level == '2': for role in visit.observers: if role.id_role == user.id_role: print('même role') is_allowed = True break elif visit.id_digitiser == user.id_role: is_allowed = True break elif role.id_organisme == user.id_organisme: is_allowed = True break if not is_allowed: raise InsufficientRightsError( ('User "{}" cannot update visit number {} ').format( user.id_role, visit.id_base_visit), 403)
def post_acquisition_framework(info_role): """ Post a dataset .. :quickref: Metadata; """ if info_role.value_filter == "0": raise InsufficientRightsError( ('User "{}" cannot "{}" a dataset').format( info_role.id_role, info_role.code_action ), 403, ) data = dict(request.get_json()) cor_af_actor = data.pop("cor_af_actor") cor_objectifs = data.pop("cor_objectifs") cor_volets_sinp = data.pop("cor_volets_sinp") af = TAcquisitionFramework(**data) for cor in cor_af_actor: # remove id_cda if None otherwise merge no working well if "id_cafa" in cor and cor["id_cafa"] is None: cor.pop("id_cafa") af.cor_af_actor.append(CorAcquisitionFrameworkActor(**cor)) if cor_objectifs is not None: objectif_nom = ( DB.session.query(TNomenclatures) .filter(TNomenclatures.id_nomenclature.in_(cor_objectifs)) .all() ) for obj in objectif_nom: af.cor_objectifs.append(obj) if cor_volets_sinp is not None: volet_nom = ( DB.session.query(TNomenclatures) .filter(TNomenclatures.id_nomenclature.in_(cor_volets_sinp)) .all() ) for volet in volet_nom: af.cor_volets_sinp.append(volet) if af.id_acquisition_framework: DB.session.merge(af) else: af.id_digitizer = info_role.id_role DB.session.add(af) DB.session.commit() return af.as_dict()
def get_user_permissions(user, code_action, code_filter_type, module_code=None, code_object=None): """ Get all the permissions of a user for an action, a module (or an object) and a filter_type Users permissions could be multiples because of user's group. The view mapped by VUsersPermissions does not take the max because some filter type could be not quantitative Parameters: user(dict) code_action(str): <C,R,U,V,E,D> code_filter_type(str): <SCOPE, GEOGRAPHIC ...> module_code(str): 'GEONATURE', 'OCCTAX' code_object(str): 'PERMISSIONS', 'DATASET' (table gn_permissions.t_oject) Return: Array<VUsersPermissions> """ id_role = user['id_role'] ors = [VUsersPermissions.module_code.ilike('GEONATURE')] q = (VUsersPermissions.query.filter( VUsersPermissions.id_role == id_role).filter( VUsersPermissions.code_action == code_action).filter( VUsersPermissions.code_filter_type == code_filter_type)) # if code_object we take only autorization of this object # no heritage from GeoNature if code_object: user_cruved = q.filter( VUsersPermissions.code_object == code_object).all() object_for_error = code_object # else: heritage cruved of the module or from GeoNature else: object_for_error = 'GEONATURE' if module_code: ors.append(VUsersPermissions.module_code.ilike(module_code)) object_for_error = module_code user_cruved = q.filter(sa.or_(*ors)).all() try: assert len(user_cruved) > 0 return user_cruved except AssertionError: raise InsufficientRightsError( 'User "{}" cannot "{}" in module/app/object "{}"'.format( id_role, code_action, object_for_error))
def __check_cruved_scope_monitoring(*args, **kwargs): module_code = kwargs.get('module_code') cruved = cruved_scope_for_user_in_monitoring_module(module_code) user = get_user_from_token_and_raise(request) permission = cruved[action] if not permission or permission < droit_min: raise InsufficientRightsError( '''User {} with permission level {} for action {} \ is not allowed to use this route for module {}, \ min permission level is {}'''.format(user['id_role'], permission, action, module_code or 'monitorings', droit_min), 403, ) return fn(*args, **kwargs)
def occurrenceHandler(request, *, occurrence, info_role): try: releve = DB.session.query(TRelevesOccurrence).get( occurrence.id_releve_occtax) except Exception as e: DB.session.rollback() raise if not releve: raise InsufficientRightsError( {"message": "not found"}, 404, ) # Test des droits d'édition du relevé si modification if occurrence.id_occurrence_occtax is not None: user_cruved = get_or_fetch_user_cruved(session=session, id_role=info_role.id_role, module_code="OCCTAX") # info_role.code_action = update_data_scope info_role = UserRigth( id_role=info_role.id_role, value_filter=user_cruved["U"], code_action="U", id_organisme=info_role.id_organisme, ) releve = releve.get_releve_if_allowed(info_role) # fin test, si ici => c'est ok occurrenceSchema = OccurrenceSchema() occurrence, errors = occurrenceSchema.load(request.get_json(), instance=occurrence) if bool(errors): return errors, 422 DB.session.add(occurrence) DB.session.commit() return occurrence
def check_if_allowed(self, info_role, action, level_scope): """ Return the releve if the user is allowed params: info_role: object from Permission """ user = UserRigth( id_role=info_role.id_role, value_filter=level_scope, code_action=action, id_organisme=info_role.id_organisme, ) if self.user_is_allowed_to(user, user.value_filter): return self raise InsufficientRightsError( ('User "{}" cannot "{}" this current releve').format( user.id_role, user.code_action), 403, )
def delete_acquisition_framework(info_role, af_id): """ Delete an acquisition framework .. :quickref: Metadata; """ if info_role.value_filter == "0": raise InsufficientRightsError( ('User "{}" cannot "{}" an acquisition_framework').format( info_role.id_role, info_role.code_action ), 403, ) if not is_af_deletable(af_id): raise GeonatureApiError( "La suppression du cadre d'acquisition n'est pas possible car des jeux de données y sont rattachées", 500, ) DB.session.query(CorAcquisitionFrameworkActor).filter( CorAcquisitionFrameworkActor.id_acquisition_framework == af_id ).delete() DB.session.query(CorAcquisitionFrameworkObjectif).filter( CorAcquisitionFrameworkObjectif.id_acquisition_framework == af_id ).delete() DB.session.query(CorAcquisitionFrameworkVoletSINP).filter( CorAcquisitionFrameworkVoletSINP.id_acquisition_framework == af_id ).delete() DB.session.query(TAcquisitionFramework).filter( TAcquisitionFramework.id_acquisition_framework == af_id ).delete() DB.session.commit() return "OK"
def get_dataset_details(info_role, id_dataset): """ Get one dataset with nomenclatures and af .. :quickref: Metadata; :param id_dataset: the id_dataset :param type: int :returns: dict<TDatasetDetails> """ dataset = get_dataset_details_dict(id_dataset) if info_role.value_filter != "3": try: if info_role.value_filter == "1": actors = [ cor["id_role"] for cor in dataset["cor_dataset_actor"] ] assert info_role.id_role in actors elif info_role.value_filter == "2": actors = [ cor["id_role"] for cor in dataset["cor_dataset_actor"] ] organisms = [ cor["id_organism"] for cor in dataset["cor_dataset_actor"] ] assert (info_role.id_role in actors or info_role.id_organisme in organisms) except AssertionError: raise InsufficientRightsError( ('User "{}" cannot read this current dataset').format( info_role.id_role), 403, ) return dataset
def get_export_pdf_acquisition_frameworks(id_acquisition_framework, info_role): """ Get a PDF export of one acquisition """ # Verification des droits if info_role.value_filter == "0": raise InsufficientRightsError( ('User "{}" cannot "{}" a dataset').format(info_role.id_role, "export"), 403, ) # Recuperation des données af = DB.session.query(TAcquisitionFrameworkDetails).get( id_acquisition_framework) acquisition_framework = af.as_dict(True) q = DB.session.query(TDatasets).distinct() data = q.filter( TDatasets.id_acquisition_framework == id_acquisition_framework).all() dataset_ids = [d.id_dataset for d in data] acquisition_framework["datasets"] = [d.as_dict(True) for d in data] nb_data = len(dataset_ids) nb_taxons = (DB.session.query(Synthese.cd_nom).filter( Synthese.id_dataset.in_(dataset_ids)).distinct().count()) nb_observations = (DB.session.query(Synthese.cd_nom).filter( Synthese.id_dataset.in_(dataset_ids)).count()) nb_habitat = 0 # Check if pr_occhab exist check_schema_query = exists( select([text("schema_name") ]).select_from(text("information_schema.schemata")).where( text("schema_name = 'pr_occhab'"))) if DB.session.query(check_schema_query).scalar() and nb_data > 0: query = ( "SELECT count(*) FROM pr_occhab.t_stations s, pr_occhab.t_habitats h WHERE s.id_station = h.id_station AND s.id_dataset in \ (" + str(dataset_ids).strip("[]") + ")") nb_habitat = DB.engine.execute(text(query)).first()[0] acquisition_framework["stats"] = { "nb_data": nb_data, "nb_taxons": nb_taxons, "nb_observations": nb_observations, "nb_habitats": nb_habitat, } if acquisition_framework: acquisition_framework[ "nomenclature_territorial_level"] = af.nomenclature_territorial_level.as_dict( ) acquisition_framework[ "nomenclature_financing_type"] = af.nomenclature_financing_type.as_dict( ) if acquisition_framework["acquisition_framework_start_date"]: start_date = dt.datetime.strptime( acquisition_framework["acquisition_framework_start_date"], "%Y-%m-%d") acquisition_framework[ "acquisition_framework_start_date"] = start_date.strftime( "%d/%m/%Y") if acquisition_framework["acquisition_framework_end_date"]: end_date = dt.datetime.strptime( acquisition_framework["acquisition_framework_end_date"], "%Y-%m-%d") acquisition_framework[ "acquisition_framework_end_date"] = end_date.strftime( "%d/%m/%Y") acquisition_framework["css"] = { "logo": "Logo_pdf.png", "bandeau": "Bandeau_pdf.png", "entite": "sinp", } date = dt.datetime.now().strftime("%d/%m/%Y") acquisition_framework["footer"] = { "url": current_app.config["URL_APPLICATION"] + "/#/metadata/af-card/" + id_acquisition_framework, "date": date, } params = {"id_acquisition_frameworks": id_acquisition_framework} else: return ( render_template( "error.html", error="Le dataset presente des erreurs", redirect=current_app.config["URL_APPLICATION"] + "/#/metadata", ), 404, ) filename = "{}_{}_{}.pdf".format( id_acquisition_framework, acquisition_framework["acquisition_framework_name"][0:31].replace( " ", "_"), dt.datetime.now().strftime("%d%m%Y_%H%M%S"), ) # Appel de la methode pour generer un pdf pdf_file = fm.generate_pdf("acquisition_framework_template_pdf.html", acquisition_framework, filename) pdf_file_posix = Path(pdf_file) return send_from_directory(str(pdf_file_posix.parent), pdf_file_posix.name, as_attachment=True)
def get_export_pdf_dataset(id_dataset, info_role): """ Get a PDF export of one dataset """ # Verification des droits if info_role.value_filter == "0": raise InsufficientRightsError( ('User "{}" cannot "{}" a dataset').format(info_role.id_role, "export"), 403, ) df = get_dataset_details_dict(id_dataset, info_role) if info_role.value_filter != "3": try: if info_role.value_filter == "1": actors = [cor["id_role"] for cor in df["cor_dataset_actor"]] assert info_role.id_role in actors elif info_role.value_filter == "2": actors = [cor["id_role"] for cor in df["cor_dataset_actor"]] organisms = [ cor["id_organism"] for cor in df["cor_dataset_actor"] ] assert info_role.id_role in actors or info_role.id_organisme in organisms except AssertionError: raise InsufficientRightsError( ('User "{}" cannot read this current dataset').format( info_role.id_role), 403, ) if not df: return ( render_template( "error.html", error="Le dataset presente des erreurs", redirect=current_app.config["URL_APPLICATION"] + "/#/metadata", ), 404, ) if len(df["dataset_desc"]) > 240: df["dataset_desc"] = df["dataset_desc"][:240] + "..." df["css"] = { "logo": "Logo_pdf.png", "bandeau": "Bandeau_pdf.png", "entite": "sinp", } date = dt.datetime.now().strftime("%d/%m/%Y") df["footer"] = { "url": current_app.config["URL_APPLICATION"] + "/#/metadata/dataset_detail/" + id_dataset, "date": date, } filename = "jdd_{}_{}_{}.pdf".format( id_dataset, df["dataset_shortname"].replace(" ", "_"), dt.datetime.now().strftime("%d%m%Y_%H%M%S"), ) # Appel de la methode pour generer un pdf pdf_file = fm.generate_pdf("dataset_template_pdf.html", df, filename) pdf_file_posix = Path(pdf_file) return send_from_directory(str(pdf_file_posix.parent), pdf_file_posix.name, as_attachment=True)
def insertOrUpdateOneReleve(info_role): releveRepository = ReleveRepository(TRelevesOccurrence) data = dict(request.get_json()) if 't_occurrences_occtax' in data['properties']: occurrences_occtax = data['properties']['t_occurrences_occtax'] data['properties'].pop('t_occurrences_occtax') if 'observers' in data['properties']: observersList = data['properties']['observers'] data['properties'].pop('observers') # Test et suppression des propriétés inexistantes de TRelevesOccurrence attliste = [k for k in data['properties']] for att in attliste: if not getattr(TRelevesOccurrence, att, False): data['properties'].pop(att) # set id_digitiser data['properties']['id_digitiser'] = info_role.id_role releve = TRelevesOccurrence(**data['properties']) shape = asShape(data['geometry']) releve.geom_4326 = from_shape(shape, srid=4326) if observersList is not None: observers = DB.session.query(TRoles).\ filter(TRoles.id_role.in_(observersList)).all() for o in observers: releve.observers.append(o) for occ in occurrences_occtax: cor_counting_occtax = [] if occ['cor_counting_occtax']: cor_counting_occtax = occ['cor_counting_occtax'] occ.pop('cor_counting_occtax') # Test et suppression # des propriétés inexistantes de TOccurrencesOccurrence attliste = [k for k in occ] for att in attliste: if not getattr(TOccurrencesOccurrence, att, False): occ.pop(att) occtax = TOccurrencesOccurrence(**occ) for cnt in cor_counting_occtax: # Test et suppression # des propriétés inexistantes de CorCountingOccurrence attliste = [k for k in cnt] for att in attliste: if not getattr(CorCountingOccurrence, att, False): cnt.pop(att) countingOccurrence = CorCountingOccurrence(**cnt) occtax.cor_counting_occtax.append(countingOccurrence) releve.t_occurrences_occtax.append(occtax) if releve.id_releve_occtax: # get update right of the user user_cruved = get_or_fetch_user_cruved( session=session, id_role=info_role.id_role, id_application=ID_MODULE, id_application_parent=current_app. config['ID_APPLICATION_GEONATURE']) update_data_scope = user_cruved['U'] # info_role.tag_object_code = update_data_scope user = UserRigth(id_role=info_role.id_role, tag_object_code=update_data_scope, tag_action_code="U", id_organisme=info_role.id_organisme) releve = releveRepository.update(releve, user, shape) else: if info_role.tag_object_code in ('0', '1', '2'): # Check if user can add a releve in the current dataset allowed = releve.user_is_in_dataset_actor(info_role) if not allowed: raise InsufficientRightsError( 'User {} has no right in dataset {}'.format( info_role.id_role, releve.id_dataset), 403) DB.session.add(releve) DB.session.commit() DB.session.flush() return releve.get_geofeature()
def export_sinp(info_role): """ Return the data (CSV) at SINP from pr_occtax.export_occtax_sinp view If no paramater return all the dataset allowed of the user params: - id_dataset : integer - uuid_dataset: uuid """ viewSINP = GenericTable('export_occtax_dlb', 'pr_occtax', None) q = DB.session.query(viewSINP.tableDef) params = request.args allowed_datasets = TDatasets.get_user_datasets(info_role) # if params in empty and user not admin, # get the data off all dataset allowed if not params.get('id_dataset') and not params.get('uuid_dataset'): if info_role.tag_object_code != '3': allowed_uuid = (str(TDatasets.get_uuid(id_dataset)) for id_dataset in allowed_datasets) q = q.filter(viewSINP.tableDef.columns.jddId.in_(allowed_uuid)) # filter by dataset id or uuid else: if 'id_dataset' in params: id_dataset = int(params['id_dataset']) uuid_dataset = TDatasets.get_uuid(id_dataset) elif 'uuid_dataset' in params: id_dataset = TDatasets.get_id(params['uuid_dataset']) uuid_dataset = params['uuid_dataset'] # if data_scope 1 or 2, check if the dataset requested is allorws if (info_role.tag_object_code == '1' or info_role.tag_object_code == '2'): if id_dataset not in allowed_datasets: raise InsufficientRightsError( ('User "{}" cannot export dataset no "{}').format( info_role.id_role, id_dataset), 403) elif info_role.tag_object_code == '1': # join on TCounting, TOccurrence, Treleve and corRoleOccurrence # to get users q = q.outerjoin( CorCountingOccurrence, viewSINP.tableDef.columns.permId == CorCountingOccurrence.unique_id_sinp_occtax ).join( TOccurrencesOccurrence, CorCountingOccurrence.id_occurrence_occtax == TOccurrencesOccurrence.id_occurrence_occtax).join( TRelevesOccurrence, TOccurrencesOccurrence.id_releve_occtax == TRelevesOccurrence.id_releve_occtax).outerjoin( corRoleRelevesOccurrence, TRelevesOccurrence.id_releve_occtax == corRoleRelevesOccurrence.columns.id_releve_occtax) q = q.filter( or_( corRoleRelevesOccurrence.columns.id_role == info_role.id_role, TRelevesOccurrence.id_digitiser == info_role.id_role)) q = q.filter(viewSINP.tableDef.columns.jddId == str(uuid_dataset)) data = q.all() export_columns = blueprint.config['export_columns'] file_name = datetime.datetime.now().strftime('%Y-%m-%d-%Hh%Mm%S') return (filemanager.removeDisallowedFilenameChars(file_name), [viewSINP.as_dict(d) for d in data], export_columns, ';')
def insertOrUpdateOneReleve(info_role): releveRepository = ReleveRepository(TRelevesOccurrence) data = dict(request.get_json()) occurrences_occtax = None if "t_occurrences_occtax" in data["properties"]: occurrences_occtax = data["properties"]["t_occurrences_occtax"] data["properties"].pop("t_occurrences_occtax") observersList = None if "observers" in data["properties"]: observersList = data["properties"]["observers"] data["properties"].pop("observers") # Test et suppression des propriétés inexistantes de TRelevesOccurrence attliste = [k for k in data["properties"]] for att in attliste: if not getattr(TRelevesOccurrence, att, False): data["properties"].pop(att) releve = TRelevesOccurrence(**data["properties"]) shape = asShape(data["geometry"]) releve.geom_4326 = from_shape(shape, srid=4326) if observersList is not None: observers = DB.session.query(User).filter( User.id_role.in_(observersList)).all() for o in observers: releve.observers.append(o) for occ in occurrences_occtax: cor_counting_occtax = [] if "cor_counting_occtax" in occ: cor_counting_occtax = occ["cor_counting_occtax"] occ.pop("cor_counting_occtax") # Test et suppression # des propriétés inexistantes de TOccurrencesOccurrence attliste = [k for k in occ] for att in attliste: if not getattr(TOccurrencesOccurrence, att, False): occ.pop(att) # pop the id if None. otherwise DB.merge is not OK if "id_occurrence_occtax" in occ and occ[ "id_occurrence_occtax"] is None: occ.pop("id_occurrence_occtax") occtax = TOccurrencesOccurrence(**occ) for cnt in cor_counting_occtax: # Test et suppression # des propriétés inexistantes de CorCountingOccurrence attliste = [k for k in cnt] for att in attliste: if not getattr(CorCountingOccurrence, att, False): cnt.pop(att) # pop the id if None. otherwise DB.merge is not OK if "id_counting_occtax" in cnt and cnt[ "id_counting_occtax"] is None: cnt.pop("id_counting_occtax") countingOccurrence = CorCountingOccurrence(**cnt) occtax.cor_counting_occtax.append(countingOccurrence) releve.t_occurrences_occtax.append(occtax) # if its a update if releve.id_releve_occtax: # get update right of the user user_cruved = get_or_fetch_user_cruved(session=session, id_role=info_role.id_role, module_code="OCCTAX") update_code_filter = user_cruved["U"] # info_role.code_action = update_data_scope user = UserRigth( id_role=info_role.id_role, value_filter=update_code_filter, code_action="U", id_organisme=info_role.id_organisme, ) releve = releveRepository.update(releve, user, shape) # if its a simple post else: # set id_digitiser releve.id_digitiser = info_role.id_role if info_role.value_filter in ("0", "1", "2"): # Check if user can add a releve in the current dataset allowed = releve.user_is_in_dataset_actor(info_role) if not allowed: raise InsufficientRightsError( "User {} has no right in dataset {}".format( info_role.id_role, releve.id_dataset), 403, ) DB.session.add(releve) DB.session.commit() DB.session.flush() return releve.get_geofeature()
def get_export_pdf_dataset(id_dataset, info_role): """ Get a PDF export of one dataset """ df = get_dataset_details_dict(id_dataset, info_role) if info_role.value_filter != "3": try: user_actor = [cor["id_role"] for cor in df["cor_dataset_actor"] if cor["id_role"]] user_actor.append(df.get('id_digitizer')) if info_role.value_filter == "1": assert info_role.id_role in user_actor elif info_role.value_filter == "2": organisms = [cor["id_organism"] for cor in df["cor_dataset_actor"] if cor["id_organism"]] assert info_role.id_role in user_actor or info_role.id_organisme in organisms except AssertionError: raise InsufficientRightsError( ('User "{}" cannot export this current dataset').format(info_role.id_role), 403, ) if not df: return ( render_template( "error.html", error="Le dataset presente des erreurs", redirect=current_app.config["URL_APPLICATION"] + "/#/metadata", ), 404, ) if len(df["dataset_desc"]) > 240: df["dataset_desc"] = df["dataset_desc"][:240] + "..." df["css"] = { "logo": "Logo_pdf.png", "bandeau": "Bandeau_pdf.png", "entite": "sinp", } df["title"] = current_app.config["METADATA"]["DS_PDF_TITLE"] date = dt.datetime.now().strftime("%d/%m/%Y") df["footer"] = { "url": current_app.config["URL_APPLICATION"] + "/#/metadata/dataset_detail/" + id_dataset, "date": date, } filename = "jdd_{}_{}_{}.pdf".format( id_dataset, df["dataset_shortname"].replace(" ", "_"), dt.datetime.now().strftime("%d%m%Y_%H%M%S"), ) try: f = open(str(BACKEND_DIR) + "/static/images/taxa.png") f.close() df["chart"] = True except IOError: df["chart"] = False # Appel de la methode pour generer un pdf pdf_file = fm.generate_pdf("dataset_template_pdf.html", df, filename) pdf_file_posix = Path(pdf_file) return send_from_directory(str(pdf_file_posix.parent), pdf_file_posix.name, as_attachment=True)
def insertOrUpdateOneReleve(info_role): """ Route utilisée depuis l'appli mobile => depreciée et non utilisée par l'appli web Post one Occtax data (Releve + Occurrence + Counting) .. :quickref: Occtax; Post one Occtax data (Releve + Occurrence + Counting) **Request JSON object:** .. sourcecode:: http { "geometry": {"type":"Point", "coordinates":[0.9008789062500001,47.14489748555398]}, "properties": { "id_releve_occtax":null,"id_dataset":1,"id_digitiser":1,"date_min":"2019-05-09","date_max":"2019-05-09","hour_min":null,"hour_max":null,"altitude_min":null,"altitude_max":null,"meta_device_entry":"web","comment":null,"id_nomenclature_obs_technique":316,"observers":[1],"observers_txt":null,"id_nomenclature_grp_typ":132, "t_occurrences_occtax":[{ "id_releve_occtax":null,"id_occurrence_occtax":null,"id_nomenclature_obs_technique":41,"id_nomenclature_bio_condition":157,"id_nomenclature_bio_status":29,"id_nomenclature_naturalness":160,"id_nomenclature_exist_proof":81,"id_nomenclature_observation_status":88,"id_nomenclature_blurring":175,"id_nomenclature_source_status":75,"determiner":null,"id_nomenclature_determination_method":445,"cd_nom":67111,"nom_cite":"Ablette = <i> Alburnus alburnus (Linnaeus, 1758)</i> - [ES - 67111]","meta_v_taxref":null,"sample_number_proof":null,"comment":null, "cor_counting_occtax":[{ "id_counting_occtax":null,"id_nomenclature_life_stage":1,"id_nomenclature_sex":171,"id_nomenclature_obj_count":146,"id_nomenclature_type_count":94,"id_occurrence_occtax":null,"count_min":1,"count_max":1 }] }] } } :returns: GeoJson<TRelevesOccurrence> """ releveRepository = ReleveRepository(TRelevesOccurrence) data = dict(request.get_json()) occurrences_occtax = None if "t_occurrences_occtax" in data["properties"]: occurrences_occtax = data["properties"]["t_occurrences_occtax"] data["properties"].pop("t_occurrences_occtax") observersList = None if "observers" in data["properties"]: observersList = data["properties"]["observers"] data["properties"].pop("observers") # Test et suppression des propriétés inexistantes de TRelevesOccurrence attliste = [k for k in data["properties"]] for att in attliste: if not getattr(TRelevesOccurrence, att, False): data["properties"].pop(att) releve = TRelevesOccurrence(**data["properties"]) shape = asShape(data["geometry"]) two_dimension_geom = remove_third_dimension(shape) releve.geom_4326 = from_shape(two_dimension_geom, srid=4326) if observersList is not None: observers = DB.session.query(User).filter(User.id_role.in_(observersList)).all() for o in observers: releve.observers.append(o) for occ in occurrences_occtax: cor_counting_occtax = [] if "cor_counting_occtax" in occ: cor_counting_occtax = occ["cor_counting_occtax"] occ.pop("cor_counting_occtax") # Test et suppression # des propriétés inexistantes de TOccurrencesOccurrence attliste = [k for k in occ] for att in attliste: if not getattr(TOccurrencesOccurrence, att, False): occ.pop(att) # pop the id if None. otherwise DB.merge is not OK if "id_occurrence_occtax" in occ and occ["id_occurrence_occtax"] is None: occ.pop("id_occurrence_occtax") occtax = TOccurrencesOccurrence(**occ) for cnt in cor_counting_occtax: # Test et suppression # des propriétés inexistantes de CorCountingOccurrence attliste = [k for k in cnt] for att in attliste: if not getattr(CorCountingOccurrence, att, False): cnt.pop(att) # pop the id if None. otherwise DB.merge is not OK if "id_counting_occtax" in cnt and cnt["id_counting_occtax"] is None: cnt.pop("id_counting_occtax") countingOccurrence = CorCountingOccurrence(**cnt) occtax.cor_counting_occtax.append(countingOccurrence) releve.t_occurrences_occtax.append(occtax) # if its a update if releve.id_releve_occtax: # get update right of the user user_cruved = get_or_fetch_user_cruved( session=session, id_role=info_role.id_role, module_code="OCCTAX" ) update_code_filter = user_cruved["U"] # info_role.code_action = update_data_scope user = UserRigth( id_role=info_role.id_role, value_filter=update_code_filter, code_action="U", id_organisme=info_role.id_organisme, ) releve = releveRepository.update(releve, user, shape) # if its a simple post else: # set id_digitiser releve.id_digitiser = info_role.id_role if info_role.value_filter in ("0", "1", "2"): # Check if user can add a releve in the current dataset allowed = releve.user_is_in_dataset_actor(info_role) if not allowed: raise InsufficientRightsError( "User {} has no right in dataset {}".format( info_role.id_role, releve.id_dataset ), 403, ) DB.session.add(releve) DB.session.commit() DB.session.flush() return releve.get_geofeature()
def cancel_import(info_role, import_id): if import_id == "undefined": return {"message": "Import annulé"}, 200 if info_role.value_filter != "3": try: if info_role.value_filter == "1": actors = [ auth[0] for auth in DB.session.query(CorRoleImport.id_role).filter( CorRoleImport.id_import == import_id).all() ] assert info_role.id_role in actors elif info_role.value_filter == "2": actors = [ auth[0] for auth in DB.session.query(CorRoleImport.id_role).filter( CorRoleImport.id_import == import_id).all() ] organisms = [ org[0] for org in DB.session.query(User.id_organisme).join( CorRoleImport, CorRoleImport.id_role == info_role.id_role).filter( CorRoleImport.id_import == import_id).all() ] assert (info_role.id_role in actors or info_role.id_organisme in organisms) except AssertionError: raise InsufficientRightsError( ('User "{}" cannot delete this current import').format( info_role.id_role), 403, ) # delete imported data if the import is already finished is_finished = (DB.session.query( TImports.is_finished).filter(TImports.id_import == import_id).one()[0]) if is_finished: name_source = "Import(id=" + import_id + ")" id_source = (DB.session.query(TSources.id_source).filter( TSources.name_source == name_source).one()[0]) DB.session.query(Synthese).filter( Synthese.id_source == id_source).delete() DB.session.query(TSources).filter( TSources.name_source == name_source).delete() # get step number step = (DB.session.query( TImports.step).filter(TImports.id_import == import_id).one()[0]) if step > 1: # get data table name user_data_name = (DB.session.query(TImports.import_table).filter( TImports.id_import == import_id).one()[0]) # set data table names archives_full_name = get_full_table_name( blueprint.config["ARCHIVES_SCHEMA_NAME"], user_data_name) imports_table_name = set_imports_table_name(user_data_name) imports_full_name = get_full_table_name("gn_imports", imports_table_name) # delete tables engine = DB.engine is_gn_imports_table_exist = engine.has_table( imports_table_name, schema=blueprint.config["IMPORTS_SCHEMA_NAME"]) if is_gn_imports_table_exist: DB.session.execute("""\ DROP TABLE {} """.format(imports_full_name)) DB.session.execute("""\ DROP TABLE {} """.format(archives_full_name)) # delete metadata DB.session.query(TImports).filter(TImports.id_import == import_id).delete() DB.session.query(CorRoleImport).filter( CorRoleImport.id_import == import_id).delete() DB.session.query(CorImportArchives).filter( CorImportArchives.id_import == import_id).delete() DB.session.commit() return {"message": "Import supprimé"}, 200