Affichage d'erreur "Unable to get row ID" après perte de droits par SearchSpec

Request description

Bonjour,

J’ai un objet métier qui possède plusieurs enregistrements (2 dans le cas ci-dessous):

Si un utilisateur n’appartient pas au groupe administrateur, il voit uniquement les enregistrements qui le concerne (ceux dont il est le responsable). Exemple ci-dessous:

Le problème, c’est que cet utilisateur doit pouvoir changer le responsable si besoin. En changeant de responsable, il ne doit plus pouvoir voir l’enregistrement car il n’en est plus responsable.

Le problème, c’est que du coup, comme il n’en a plus la visibilité, au moment où il enregistre, il obtient cette erreur ci-dessous (Thomas GERAUD change le responsable. Ce n’est plus lui, mais Florent LAUZET):

Voici comment les droits de visibilités sont gérés :

@Override
public void postLoad() {
	if(!getGrant().hasResponsibility("DDV_SUPERADMIN") && !getGrant().hasResponsibility("DDV_ASSISTANT")){
		if(getGrant().hasResponsibility("DDV_MANAGER")){
			setDefaultSearchSpec("t.ddv_pow_responsible IN " + this.getAllResponsibleOfFundForTeamManager());
		} else {
			setDefaultSearchSpec("t.ddv_pow_responsible = " + getGrant().getUserUniqueId());
		}
	} else{
		setDefaultSearchSpec("t.ddv_pow_responsible IS NOT NULL");
	}
}

Avez-vous une idée de comment résoudre ce problème ?

PS : Je précise que l’enregistrement est bel et bien sauvegardé malgré l’erreur.

Technical information

Instance /health
[Platform]
Status=OK
Version=5.1.36
BuiltOn=2022-03-25 23:37
Git=release/8329db12a092c6c91775901c9f207681792bbea1
Encoding=UTF-8
EndpointIP=10.201.117.42
EndpointURL=http://siparex-simplicite-dev-745fcf686c-ptkfp:8080
TimeZone=Europe/Paris
SystemDate=2022-04-01 10:41:18
Simplicité logs
NA

Ce comportement UI est effectivement déroutant mais semble difficile à contourner. Le plus simple est de forcer l’utilisation du formulaire et du save&close,

Idéalement, j’imagine qu’il faudrait pouvoir envoyer un warning particulier dans le postValidate qui permette de demander une confirmation avant enregistrement:

  1. save par le user
  2. RDG dans le postValidate: si onChange => warning de confirmation
  3. OK / Cancel par le user
  4. Si OK => affichage de l’erreur, avec message plus user-friendly “Vous n’avez pas les droits pour accéder à ces données”

@Francois t’en penses quoi?

Des idées :

  • On peut forcer/retourner un javascript ou un redirect statement (vers la liste ou quelque chose d’habilité) dans le postSave si le responsable a changé et que ce n’est plus moi-même.

  • Interdire de modifier le responsable via l’objet directement, et créer une Action “Changer de responsable” avec un champ de confirmation FK vers un responsable + ses champs joints et une méthode back qui fait l’update et le redirect vers un truc autorisé.

1 Like

Merci,

J’avoue ne pas avoir tout compris. Mais j’ai essayé de set de nouveau les droits dans le postSave() en prenant la ligne actuelle en plus dans les droits. Ce qui fait que tant que l’utilisateur ne s’est pas déconnecté de sa session, il voit toujours la ligne actuelle et donc il peut la modifier.

Code :

if(!getGrant().hasResponsibility("DDV_SUPERADMIN") && !getGrant().hasResponsibility("DDV_ASSISTANT")){
	if(getGrant().hasResponsibility("DDV_MANAGER")){
		setDefaultSearchSpec("t.row_id IN " + this.getAllResponsibleOfFundForTeamManager());
	} else {
		setDefaultSearchSpec("t.row_id = " + this.getRowId() + " OR t.ddv_pow_responsible = " + getGrant().getUserUniqueId());
	}
}

Code complet du postSave() + postLoad() :

@Override
public void postLoad() {
	if(!getGrant().hasResponsibility("DDV_SUPERADMIN") && !getGrant().hasResponsibility("DDV_ASSISTANT")){
		if(getGrant().hasResponsibility("DDV_MANAGER")){
			setDefaultSearchSpec("t.row_id IN " + this.getAllResponsibleOfFundForTeamManager());
		} else {
			setDefaultSearchSpec("t.ddv_pow_responsible = " + getGrant().getUserUniqueId());
		}
	} else{
		setDefaultSearchSpec("t.ddv_pow_ag_id IS NOT NULL");
	}
}

@Override
public String postSave(){
	String status = "";
	
	if(!this.getFieldValue("ddvPowAgId").equals("")){
		status = getGrant().simpleQuery("SELECT m.ddv_met_state FROM ddv_general_meeting m WHERE m.row_id = " + this.getFieldValue("ddvPowAgId"));
	}

	if(status.equals("GM_RESPONSIBLE_POWER_VALIDATE") && (getField("ddvPowValidate").hasChanged() || getField("ddvPowResponsible").hasChanged() || getField("ddvPowManualName").hasChanged())){
		this.messageToInform();
		this.setMissingRespValid();
	}
	
	if(status.equals("GM_RESPONSIBLE_TEAM_SIGN") && getField("ddvPowIsTeamDocumentSign").hasChanged()){
		this.messageToInformManager();
		this.allValidatedSigned();
	}
	
	if(!getGrant().hasResponsibility("DDV_SUPERADMIN") && !getGrant().hasResponsibility("DDV_ASSISTANT")){
		if(getGrant().hasResponsibility("DDV_MANAGER")){
			setDefaultSearchSpec("t.row_id IN " + this.getAllResponsibleOfFundForTeamManager());
		} else {
			setDefaultSearchSpec("t.row_id = " + this.getRowId() + " OR t.ddv_pow_responsible = " + getGrant().getUserUniqueId());
		}
	}
	
	return null;
}

Il semble y avoir un défaut d’implémentation qui empêche la prise en compte correcte de la solution théorique (redirectStatement dans le postSave). On investigue et on revient vers vous dès que possible.

Solution testée
package com.simplicite.objects.Demo;

import java.util.*;
import com.simplicite.util.*;
import com.simplicite.util.tools.*;

/**
 * Business object DemoSupplier
 */
public class DemoSupplier extends ObjectDB {
	private static final long serialVersionUID = 1L;
	
	@Override
	public void postLoad() {
		setDefaultSearchSpec(getDefaultSearchSpec() + " AND sup_name LIKE '%Computers%'");
	}
	
	@Override
	public String postSave() {
		if(getField("demoSupName").hasChanged())
			return HTMLTool.redirectStatement(HTMLTool.getListURL(this, null));
		
		return null;
	}
}

redirect

Pour le moment, la solution que j’ai écrit au dessus fonctionne pour moi.

Oui l’approche est valide.

Remarque: Souvent, à l’exception du postLoad, on a tendance tendance à surcharger la defaultSearchSpec, ce sera ainsi cumulatif si l’utilisateur modifie plusieurs Pouvoirs:

Cumulatif:

setSearchSpec(getSearchSpec()+" OR t.row_id = " + this.getRowId());

Non Cumulatif:

// on repart à chaque fois de la searchSpec
setSearchSpec(getDefaultSearchSpec()+" OR t.row_id = " + this.getRowId());
1 Like

Le fonctionnement sera amélioré au prochain build 5.1.38 :

Depuis un update en formulaire :

  • Affiche les messages (ou applique les HTMLTool.javascriptStatement / HTMLTool.redirectStatement) issus du hook postSave ou postUpdate
  • Sinon par défaut, affiche un toast “L’accès à l’objet ne vous est plus autorisé” + redirect vers la liste de l’objet

Depuis un update en liste (fille ou non) :

  • aucun message affiché / ni redirect
  • ignore les messages des hooks car la ligne n’existe plus pour les afficher
  • la ligne disparait simplement de la liste actualisée au save

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.