[Gelöst] Teile vom Report entsprechend der User Rolle sichtb

21. Februar 2006 17:43

Hallo,

ich möchte einige Reports so modifizieren, dass der angemeldet User in Abhängigkeit seiner Rolle die nur ihn betreffenden Inhalte sehen kann.

Bsp.: Wenn der User nicht die Rolle "SUPER" hat, darf er nur seinen eigenen Zeiteinträge im Report "Zeiterfassung" sehen. Habt ihr vielleicht eine Idee?

Gruß

Markus
Zuletzt geändert von mgerhartz am 10. April 2006 13:32, insgesamt 1-mal geändert.

21. Februar 2006 19:02

Entweder die ganze Geschichte im Report ausprogrammieren, oder die Sicherheitsfilter verwenden.

Auszug aus der Hilfe:
Das Feld Sicherheitsfilter
Dieses Feld enthält den Sicherheitsfilter, der den Zugriff einzuschränkt, den diese Rolle auf die Daten in dieser Tabelle hat.

21. Februar 2006 20:30

Hi Martin,

danke für den Tipp. Werde mich morgen gleich mal auf Arbeit dran setzen. Später mehr...

Markus

21. Februar 2006 21:47

Hinweis: Der Sicherheitsfilter funktioniert nur auf dem SQL-Server, nicht beim Navision-Database-Server.

Die Gruppenzugehörigkeit ist in der Tabelle 2000000003 "Member Of" ("Mitglied von") gespeichert:
Code:
MemberOf.SETRANGE("User ID",USERID);
MemberOf.SETRANGE("Role ID",'SUPER');
IF NOT MemberOf.FIND('-') THEN
  UserTimeRegister.SETRANGE("User ID",USERID);

22. Februar 2006 09:44

Eine weitere Möglichkeit wäre eine Zusatzberechtigung einzubauen (weiss nicht ob das Standard ist, falls nicht: ist im Grunde eine Tabelle in welcher zu den Bentutzern mehrere Boolean-Felder eingebaut sind zum Beispiel: "Darf alle sehen", diese Felder können dann in Reports oder Forms abgefragt werden.) oder wäre das in deinem Fall zu "flach"?

22. Februar 2006 10:48

>>Hinweis: Der Sicherheitsfilter funktioniert nur auf dem SQL-Server, >>nicht beim Navision-Database-Server.
Hoppla. Das wusste ich nicht.

22. Februar 2006 14:31

Hallo Leute,

@JanV: Sicherlich funktioniert das, jedoch müsste ich dann ja für jeden User die Rechte in der Tabelle einzeln zuweisen, oder? Jedenfalls haben wir eine Menge User ;-)

@Timo: In welchen Trigger muss ich denn den Code packen? In den "Report - OnPreReport"?

22. Februar 2006 15:11

Hallo mgerhartz,

ja stimt schon, das müsstest du dann jedem User zuweisen, Vorteil wäre aber, dass du Mitglieder einer Rolle nochmals untereinander aufteilen kannst, verstehst wie ich mein?

Bezüglich dem Trigger; kommt drauf an was genau du bewirken willst; willst du eine Fehlermeldung ausgeben wenn ein Benutzer einen Report mit Filtern ausserhalb seiner Genehmigung ausdrucken will? Dann im "OnPreReport"-Trigger. Wenn du willst dass der Report einfach nur die genehmigten Datensätze ausgegeben willst würde ich die Prüfung im OnAfterGetRecord in Verbindung mit einem Skip einbauen, das ist aber dann die langsamere Methode.

Gruß Jan

22. Februar 2006 16:12

Hi Jan,

wir haben allerding ca. 2.000 User. Das ist doch ein wenig vie, um jeden User seine Rechte in der Tabell zuzuweisen.

Eine einfache Fehlermeldung reicht da auch nicht aus. Immerhin sind das persönlich Daten, die nur die Admins mit SUPER Rechten sehen dürfen. Jeder "gewöhnliche" User soll nur seine eigenen Einträge sehen. Also werde ich wohl den Code in den OnAfterGetRecord Trigger schreiben müssen. Probiers gleich mal aus.....

22. Februar 2006 16:23

>>wir haben allerding ca. 2.000 User
2000 User auf einer NativDB?

Keine Probleme?

22. Februar 2006 16:25

Ok, 200 User sind wirklich ein bischen heftig :-).

Hmm ich würde das dann am ehesten folgendermaßen lösen:
Du erstellest einen Link, bei Klick auf diesem Link prüftst du ob der Benutzer SUPER-Rechte hat, wenn ja kommt die Requestform und der Benutzer kann beliebig Filter setzen, wenn nein lässt du die Requestform weg, filterst den Record vor Aufruf des Reports auf den entsprechenden Datensatz ein (anhand der User-ID) und startest dann den Report.

Code wäre ungefähr so:
Code:

Control - OnPush()

MemberOf.SETRANGE("User ID",USERID);
MemberOf.SETRANGE("Role ID",'SUPER');
IF NOT MemberOf.FIND('-') THEN begin
  UserTimeRegister.SETRANGE("User ID",USERID);
  REPORT.RUN(123456,FALSE,FALSE,UserTimeRegister);
end else
  Report.Run(123456,TRUE);



Dann sparst du dir das rumfummeln in den eizelnen Triggern und der Report dürfte schneller laufen.

Gruß Jan

Edit: Klammer vergessen ;-)

22. Februar 2006 16:41

Das stimmt schon mit den ca. 2000 usern. Wir benutzen ja auch keine native DB.

22. Februar 2006 17:38

Habe jetzt einen Link erstellt und den Code entsprechend im On Push -Trigger eingefügt. Bekomme jetzt folgende Fehlermeldung: sieh Screenshot.

Was habe ich denn falsch gemacht. Er sollte doch den Report starten, nur lediglich die Daten ausblenden, die nicht den User betreffen, der gerade angemeldet ist.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

22. Februar 2006 17:43

Die Fehlermeldung sagt aus, dass du einen Record filtern willst welcher in deinem Report gar nicht vorhanden ist. Hast du ein Dataitem "User Time Register" in deinem Report?

22. Februar 2006 17:52

Kleiner Nachtrag: Wenn ich mich als Admin mit der Rolle SUPER anmelde, funktioniert der Link zum Report. Scheinbar wird also die komplette Tabelle gesperrt, wenn man nicht mit der Rolle SUPER angemeldet ist.

Muss ich jetzt noch eine Rolle für den Zugriff auf die Tabelle "MemberOf" bzw. "UserTimerRegister" mit entsprechendem Sicherheitsfilter erstellen?

22. Februar 2006 17:54

Nee nee, der Grund warums funktioniert wenn du mit SUPER-User angemeldet bist ist der, dass da keine Tabelle gefiltert wird, der Report wird ganz normal gestartet.

Wie heisst denn die Tabelle auf welcher der Bericht beruht?

22. Februar 2006 17:58

@Jan:

Nein habe ich nicht. Ich habe quasi den Code von Dir übernommen und lediglich die Rec Variable mit entsprechenden Subtype erstellt. Ich dachte, ich benötige die Tabelle UserTimeRegister um die User ID zu prüfen. Bin ein wenig verwirrt?!? :-|

22. Februar 2006 18:01

Das sind gleich mehrere, die voneinader abhängig sind. Das erste DataItem heist "Leistungsart". Soll mit dem SETRANGE etwa auf das Feld USER ID abgegrenzt werden? Die Tabelle "Leistungsart" hat nämlich kein Feld mit der USER ID.

22. Februar 2006 18:02

Aaah, ich habe allerding eine Tabelle User als 2. DataItem und dort gibt es die Spalte User ID. Ich muss also darauf abgrenzen, oder? :roll:

22. Februar 2006 18:05

Ok, also es funktioniert wie folgt, der Code den ich dir geschrieben hatte war folgendermaßen aufgebaut:

1. Teil:
Code:
Control - OnPush()

MemberOf.SETRANGE("User ID",USERID);
MemberOf.SETRANGE("Role ID",'SUPER');


An dieser Stelle filtern wir die Tabelle "MemberOf" auf die aktuelle Benutzer-ID ein (in der Klammer steht als erstes das zu filternde Feld und als Zweites der Wert nach dem gefiltert wird.)

2. Teil:
Code:
IF NOT MemberOf.FIND('-') THEN begin
  UserTimeRegister.SETRANGE("User ID",USERID);
  REPORT.RUN(123456,FALSE,FALSE,UserTimeRegister);
end else
  Report.Run(123456,TRUE);


Wenn das System keinen Eintrag zum aktuellen Benutzer findet soll folgendes passieren:
Die Tabelle "UserTimeRegister" wird auf den aktuellen Benutzer gefiltert, im Anschluss wird der Report aufgerufen und die Tabelle "UserTimeRegister" übergeben, dies bedeutet, dass in deinem Report ein Dataitem "UserTimeRegister" vorhanden sein muss, ansonsten kommt die entsprechende Fehlermeldung. Du musst also im Grunde nur das "UserTimeRegister" durch die Tabelle ersetzen, welche in deinem Report "eingebaut" ist, dann müsste das klappen.

Du hast doch das Feld "User-ID" in der Tabelle auf welcher dein Report beruht, oder?

Gruß Jan

22. Februar 2006 18:15

Hi Jan,

so ich muss jetzt die Beine in Hand nehmen. Mein Zug geht gleich. Schon einmal vielen Dankf für Deine Hilfe. Ich setze mich gleich im Zug hin und werde weiter basteln. Das Ergebnis werde ich natürlich wieder posten. So long und schönen Feierabend...

Markus

22. Februar 2006 18:16

Alles klar, schönen Feierabend! :-)

23. Februar 2006 17:52

Und? was hat die Bastelei ergeben?

Nicht, dass ich neugierig wäre..... :mrgreen:

23. Februar 2006 17:53

Das hab ich mich auch schon gefragt :-)

23. Februar 2006 17:55

>>Das stimmt schon mit den ca. 2000 usern. Wir benutzen ja auch keine native DB.

Na also, dann kannst Du doch die Sicherheitsfilter verwenden und die Bastelei sein lassen :-D