bituniverse.com Foren-Übersicht bituniverse.com
Entwickler Forum
 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen   RegistrierenRegistrieren 
 ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Entwicklung von neuem Forum
Gehe zu Seite Zurück  1, 2, 3, 4, 5  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    bituniverse.com Foren-Übersicht -> OFF-Topic und Sonstiges
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Slava
Administrator


Anmeldedatum: 16.01.2007
Beiträge: 282
Wohnort: Köln

BeitragVerfasst am: Fr 23 Nov, 2007 23:39    Titel: Antworten mit Zitat

Simon W. hat Folgendes geschrieben:
ja ok, bei diesem ansatz ist das natürlich möglich, nur kann man einzelnen benutzern/gruppen keine rechte verweigern.
die gruppe "gott" gefällt mir übrigens Wink


natürlich kann man den einzelnen gruppen was verweigern ( wenn man ein wenig anpasst) und es ist auch möglich für jeden einzelnen user die rechte anlegen, aber datenbank wird dadruch mehr belastet, also deshalb ist es einfacher einen User zu Gruppe zuzuordnen, um den riesigen arbeitsaufwand bei vergeben von allen möglichen Rechten bei jedem einzelnen User zu sparen.
Bei diesem Einsatz ging es darum wenigstens ein Recht für Lesen von Resource bei dem User abzufangen. Aus diesem Grund habe ich auch Zugehörigkeit zu allen Gruppen von einem User abgefragt. So eine vorgehensweise ist auch sinnvoll, da es traurig wäre wenn dem 'Admin' eine Resource verweigert wurde, nur weil er zusätzlich auch zu einer anderer Groppe gehört.

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dr.e.
Moderator


Anmeldedatum: 04.11.2007
Beiträge: 98

BeitragVerfasst am: So 25 Nov, 2007 23:41    Titel: Antworten mit Zitat

Folgende Hinweise:

- Rollen sollten eine Sammlung von Berechtigungen auf Funktionen sein
- Die Qualität von Rechten sollte man in den Beziehungen speichern, bzw.
unterschiedliche Beziehungen für das Recht "Löschen", "Bearbeiten", ...
definieren.

Das Tabellendesign ist zudem ein wenig ungenerisch, da man so etwas wie Rechte auf Objekte vergeben können sollte.


_________________

Grüße,
Dr.E.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Have a look at www.adventure-php-framework.org!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Simon W.
Anti-verdenglischungs-Abgeordneter


Anmeldedatum: 05.11.2007
Beiträge: 283
Wohnort: Aachen

BeitragVerfasst am: Mo 26 Nov, 2007 01:29    Titel: Antworten mit Zitat

Ja, wir bräuchten ein System, das mit mehreren Bereichen umgehen kann und nicht nur auf eine Forenstruktur zugeschnitten ist. Jedes Modul(Bereich) sollte unabhängig Rechte für bestimmte Aktionen abfragen und setzen können und das wiederum abhängig von "Objekten", wie dr.e. es nannte.

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Slava
Administrator


Anmeldedatum: 16.01.2007
Beiträge: 282
Wohnort: Köln

BeitragVerfasst am: Mi 28 Nov, 2007 02:18    Titel: Antworten mit Zitat

dr.e. hat Folgendes geschrieben:
Folgende Hinweise:

- Rollen sollten eine Sammlung von Berechtigungen auf Funktionen sein
- Die Qualität von Rechten sollte man in den Beziehungen speichern, bzw.
unterschiedliche Beziehungen für das Recht "Löschen", "Bearbeiten", ...
definieren.

Das Tabellendesign ist zudem ein wenig ungenerisch, da man so etwas wie Rechte auf Objekte vergeben können sollte.


ich kann das auch ginerisch machen um eine universale Lösung zu haben (die ACL Konzepte sind mir bekannt) , dann ist aber die performance hin. wir dürfen nicht vergessen, dass die Resource in unserem Fall eine tabellenzeile ist, und ich kann mir leider nicht leisten für jede zeile eine extra ACL abfrage starten.
zu viele Abstractionen brauchen wir gar nicht.
es wird eine Model mit einer methode erstellt, die nötige Informationen liefert. es geht um Forum und die Tabellen werden auch für Forum gemacht (mit ausname von User-tabelle)und zwar so, dass wir auch Performancemassig in grünem bereich liegen.
Wenn wir datenmodel erstellen, bin ich eigentlich dafür, dass nur wenige Leute die Model-classe mit passenden Methoden erstellen.
Alle andere nutzen das nur, und brauchen sich erst mit den technischen fragen von DB-Abfragen gar nicht bescheftegen, ob die Daten von DB oder Cach kommen ist erst für die Jenige, die mit Controller und View beschäftigen unrelevant. Wir müssen noch ganu nachschauen, wie viele querys eigentlich benötigt werden, und wenn das zu viele sind, wird vermutlich die Model-Classe die einzelne Methoden zum laufzeit laden (bzw in mehrere Models geteilt) um die Anwendung zu entlasten (das selbe gilt auch für die Controller).
Wir versuchen gerade mit dem Jens verschiedene Varianten durch Kopf zu jagen um ein optimaler Weg zwischen Geschwindigkeit, Verständlichkeit von Code und Anpassungsfähigkeit von software zu ermöglichen. Vermutlich werden wir auch die Massnamen treffen , die nicht unbedingt an die allgemeine Vorstellung von Datenhaltung entsprechen um Datenbank zu schönen und der Einsatz von software auch bei biliganbieter zu ermöglichen.

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dr.e.
Moderator


Anmeldedatum: 04.11.2007
Beiträge: 98

BeitragVerfasst am: So 02 Dez, 2007 15:50    Titel: Antworten mit Zitat

Hallo Slava,

Zitat:
zu viele Abstractionen brauchen wir gar nicht.
es wird eine Model mit einer methode erstellt, die nötige Informationen liefert. es geht um Forum und die Tabellen werden auch für Forum gemacht (mit ausname von User-tabelle)und zwar so, dass wir auch Performancemassig in grünem bereich liegen.


Da würde ich vorsichtig sein, denn meiner Einschätzung nach sind die Anforderungen noch nicht wirklich klar definiert. In diesem Fall muss man mehr Generik walten lassen um spätere Erweiterungen auch implementieren zu können. Hier sollte man auch hinsichtlich der GUI möglichst frei in seiner Erweiterbarkeit bleiben, denn neue Features können sonst eine komplette Überarbeitung notwenig machen.


Zitat:
Alle andere nutzen das nur, und brauchen sich erst mit den technischen fragen von DB-Abfragen gar nicht bescheftegen, ob die Daten von DB oder Cach kommen ist erst für die Jenige, die mit Controller und View beschäftigen unrelevant. Wir müssen noch ganu nachschauen, wie viele querys eigentlich benötigt werden, und wenn das zu viele sind, wird vermutlich die Model-Classe die einzelne Methoden zum laufzeit laden (bzw in mehrere Models geteilt) um die Anwendung zu entlasten (das selbe gilt auch für die Controller).


Das ist ein gutes API-Konzept. Man sollte an dieser Stelle einen usermanagementManager bereitstellen, der einem die notwenigen Information geben kann. Das sind (sicher nicht vollständig):

- getUserByID(): Alle Daten zu einem Benutzer. Von diesem User-Objekt kann man sich dann die Gruppen, ACLs, ... geben lassen
- getUserList(): Liste von Benutzern für diverse Anzeigen. Man sollte der Methode noch mitgeben können welche Attributre u.U. mitgeladen werden sollen (ACLs, Gruppen, ...), damit man performancetechnisch gut gewappnet ist.
- getGroupByID(): Selbe Implementierung wie für Benutzer
- getGroupList(): Selbe Implementierung wie für Benutzer
- getRoleByID(): Rolle mit ihren ACL-Definitionen liefern
- getRoleList(): Liste der Rollen, Implementierung wie bei Benutzern
- getUsersByGroup(): Liste von Benutzern per Gruppe liefern
- getUsersByRole(): Liste von Benutzern per Rolle liefern
- save*(): Speicherung von Objekten

Der Anwender kann dann einfach den Manager verwenden und muss sich um den Rest nicht kümmern. Wichtig ist dabei, dass sich die Business-Schicht um die Auflösung der Beziehungen und die Datenschicht um die Datenhaltung kümmert. Nehmen wir an, dass ein Benutzer mit einer neuen Gruppe ausgestattet worden ist, dann muss das die Business-Schicht erkennen und die neue Gruppe speichern, ehe die Beziehung zwischen Benutzer und Gruppe aufgebaut werden kann.

Alles in allem sehr komplex und zum Thema Performance nicht gerade ein einfaches Unterfangen. Sollte ich zu diesem Bereich etwas beitragen können, bitte melden.
-
-


_________________

Grüße,
Dr.E.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Have a look at www.adventure-php-framework.org!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Slava
Administrator


Anmeldedatum: 16.01.2007
Beiträge: 282
Wohnort: Köln

BeitragVerfasst am: Do 13 Dez, 2007 01:26    Titel: Antworten mit Zitat

so
jetzt mache ich mir ernst die Gedanken über Usermanagement.

Wie schon alle bemerkt haben ist es natürlich optimal ein object oder eine funktion als Resource zu definieren, die ein bestimter Satzt von Rechten hat.
Dan würde ein User, Bzw Usergroup eine Rolle bekommen, die zu einer Resource ein bestimmter Rechten-Set hat.
bei diesem Perfektem fall, wäre es sehr leicht alles zu defenieren.
Ich könnte schon wärend Dispatching-prozess die benötigte RechtenSet zu dem Angefördertem Controller->acrionMethod anfördern, der als Resource deklariert ist.
Wie sieht es jetzt aber aus mit einzelner Tabellenzeile?
Zbs Forumsübersicht oder jeder einzelner Posting.
ich muss jede einzelne Zeile als ein Object betrachten und zusätzliche infos anfördern.
In diesem Fall muss ich ein Objectorientierte schicht über Datenbank ziehen, die es erlaubt jede einzelne Zeile als getrennte Resource zu betrachten. Dabei wird es bei manchen Stellen, wie zbs Posting nicht nur auf Groupenebene, sondern auch Userebene unterschiede geben (user darf sein posting editieren).
Schaut mal wie viele ACL es geben kann
1)Forumübersicht
ACL-1 Gruppe zu jeder einzelner ForumNamen Zeile (lesen,bearbeiten,löschen)
ACL-2 Gruppe zu Tabelle ForumNamen (nur für einfügen)
ACL-3 Gruppe zu Controller selbst (ausführen)
ACL-4 Gruppe zu Modul (ansehen)
2)ThreadÜbersicht
ACL-1 Gruppe + User zu Thread-Zeile(lesen,löschen,moderieren,verschieben,bearbeiten)
ACL-2 Gruppe zu Thread-Tabelle (einfügen)
ACL-3 Controller, Method, Modul (lesen)
.......
Also eine ganze Menge von Rechten, die Teilweise gar nicht über Usermanagement-Tool sondern direkt bei Programmieren fest implementiert.
Jetzt kommt die Frage wie schwer das alles zu machen ist. also auf sql-ebene kann ich mir das Gut vorstellen. Werden wir aber darüber viel zu viel abstracten Schichten ziehen, dann werden wir schnell feststellen, dass dieser Weg uns keine Vorteile bringt und macht schnell die Anwendung unübersichtlich.
die von Dr.e vorgeschlagene Methoden sind natürlich sehr wichtig, aber die meiste von diesen Methoden werden kaum alleine aufgerufen, sondern als ein Teilmenge von einer Sql-Abfrage, da ich mich für eine Rolle erst dann interessiere, wenn ich eine Resource und seine Rechte habe, auf die die Rolle zugreifen möchte. Werde ich an dieser Stelle von Sql in die Richtung von verständlichen und passenden Objecten und Methodennamen abweichen, dann werde ich gezwungen die reqrusive sqlabfragen im Hintergrund zu jagen, was sehr viel Performance in Anspruch nimmt und auch eine Menge von zusätzlichen Classen programmieren.

Zum Usermanagement:
ich schlage vor, dass wir User-tabelle nicht unbedingt als Forumuser-Tabelle betrachten, da es vorkommen kann, dass wir die Userdaten auch bei zukunftigen Modulen verwenden können.
Usermanagement muss meine Meinung nach so programmiert werden, dass wir die User bezogene(User_id,Name, email, icq_nr...) und forum-user bezogene Daten (Nikname, Signatur,...) trennen könnten.

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dr.e.
Moderator


Anmeldedatum: 04.11.2007
Beiträge: 98

BeitragVerfasst am: Do 13 Dez, 2007 10:37    Titel: Antworten mit Zitat

Hallo Slava,

bei deinen Betrachtungen muss du aufpassen, dass du zwischen Gruppen und Rollen unterscheidest. Eine Rolle wiederum beinhaltet verschiedene Permissions. Eine Permission ist das "Recht" eine Funktion innerhalb einer Applikation auszuführen. Dieses "Recht" ist natürlich hardcoded in der Applikation drin, denn die Applikation implementiert diese Funktionen ja.

Wie hinterher das Datenbank-Layout aussieht ist ersmal unabhängig der Betrachtung der API des Usermanagers. Dieses sollte die von mir vorgeschlagenen Methoden haben, mit im Action-Controller verwendet werden können (z.B. Laden der Permissions eines Benutzers). Wie du das hinterher allgemein zur Verfügung stellst, sprich ob eine Instanz des Benutzer-Objekts jedem Action-Controller mitgegeben wird, ist eine andere Sache.


//EDIT:
Nochmal grundsätzlich zum Entwicklungsprozess derartiger Module: du musst dir immer zuerst die API überlegen, dann die interne Strukturierung desselben und dann erst die Datenbank-Strategie. Diese Vorgehendweise entspricht einem Top-Down-Approach, der den Vorteil hat, dass du das Tabellen-Desig unabhängig vom verhalten hinterher machen kannst.


_________________

Grüße,
Dr.E.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Have a look at www.adventure-php-framework.org!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Slava
Administrator


Anmeldedatum: 16.01.2007
Beiträge: 282
Wohnort: Köln

BeitragVerfasst am: Do 13 Dez, 2007 20:03    Titel: Antworten mit Zitat

dr.e. hat Folgendes geschrieben:
Hallo Slava,

bei deinen Betrachtungen muss du aufpassen, dass du zwischen Gruppen und Rollen unterscheidest. Eine Rolle wiederum beinhaltet verschiedene Permissions. Eine Permission ist das "Recht" eine Funktion innerhalb einer Applikation auszuführen. Dieses "Recht" ist natürlich hardcoded in der Applikation drin, denn die Applikation implementiert diese Funktionen ja.


Hi Dr.e.
wie würdest du an die Sache gehen?
Wenn wir jetzt ein Klassischer ACL beispiel zbs von ZendFramework nehmen framework.zend.com
es ist klar, dass wie ich es objectorientiert machen kann, aber ich ich weis nicht ganz, wie ich das auf Db-ebene mit passender Performance an die vorprogrammierte ACL Objecte binde. Ich will nicht sagen, dass es nicht möglich ist, aber mir fehlt irgendwie Faden um das ginerisch zu realisieren.

Zu Usermanagement:
Ich stelle mir das so vor.
---------------
User und ForumUser
Tabelle User wird Name, Vorname, User_id, E-Mail, icq_nr, ....
bekommen.
Tabelle Forum_User wird mit User durch User_id verknüpft und wird nur forumbezogene Sachen , wie Nikname, Signatur erhalten.
das wird für uns ein Zusätzlicher Join bedeuten, wird aber erlauben die Tabelle User in anderen Modulen verwenden.
Wird jemand sich entscheiden ein Onlineshop zu programmieren, dann kann er automatisch die User in Forum reinlassen.
---------------------------------
Verwaltung
Globale userbezogene Informationen ändern bzw bearbeiten.
Name, Email, Adresse, von Tabelle User muss getrennt von ForumUser bearbeitet werden.

Grupenverwaltung.
(Gruppenverwaltung muss man nicht unbedingt nur in Zusammenhang mit dem Forum betrachten)
1) neue gruppe erzeugen
2) gruppe editieren und löschen.
3) User an eine Gruppe binden, bzw löschen
-------------

Die Tabellenstruktur für Gruppen, User und Forumuser werde ich Heute vorbereiten.
OT
Ich warte noch, was Jens mit meinem Code einrichtet (ich bin mir jetzt nicht siecher, dass da noch meine code drin steht Smile )
Wenn die Tabellenstruktur von dem Forum selbst und die Resourcen, die betimmte Rechte fordern klar sind, dann werden wir bei Usermanagement zusetzlich die Rechteverwaltung machen müssen.

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Slava
Administrator


Anmeldedatum: 16.01.2007
Beiträge: 282
Wohnort: Köln

BeitragVerfasst am: Fr 14 Dez, 2007 12:19    Titel: Tabellenstruktur Antworten mit Zitat

bitte der sternchen im se* durch 'x' ersetzen :)
Code:
  1. -- --------------------------------------------------------
  2.  
  3. --
  4. -- Tabellenstruktur für Tabelle `forum_user`
  5. --
  6.  
  7. CREATE TABLE IF NOT EXISTS `forum_user` (
  8.   `user_id` int(8) NOT NULL,
  9.   `user_active` tinyint(1) default '1',
  10.   `user_lastvisit` int(11) NOT NULL,
  11.   `user_timezone` decimal(5,2) NOT NULL default '0.00',
  12.   `user_viewemail` tinyint(1) NOT NULL default '0',
  13.   `user_newpasswd` varchar(32) collate utf8_unicode_ci default NULL,
  14.   PRIMARY KEY  (`user_id`)
  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  16.  
  17. --
  18. -- Daten für Tabelle `forum_user`
  19. --
  20.  
  21.  
  22. -- --------------------------------------------------------
  23.  
  24. --
  25. -- Tabellenstruktur für Tabelle `groups`
  26. --
  27.  
  28. CREATE TABLE IF NOT EXISTS `groups` (
  29.   `group_id` int(8) NOT NULL auto_increment,
  30.   `group_name` varchar(40) collate utf8_unicode_ci NOT NULL,
  31.   `group_description` varchar(255) collate utf8_unicode_ci NOT NULL,
  32.   PRIMARY KEY  (`group_id`)
  33. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
  34.  
  35. --
  36. -- Daten für Tabelle `groups`
  37. --
  38.  
  39.  
  40. -- --------------------------------------------------------
  41.  
  42. --
  43. -- Tabellenstruktur für Tabelle `users`
  44. --
  45.  
  46. CREATE TABLE IF NOT EXISTS `users` (
  47.   `user_id` int(11) NOT NULL default '0',
  48.   `username` varchar(64) collate utf8_unicode_ci default NULL,
  49.   `passwd` varchar(32) collate utf8_unicode_ci default NULL,
  50.   `first_name` varchar(128) collate utf8_unicode_ci default NULL,
  51.   `last_name` varchar(128) collate utf8_unicode_ci default NULL,
  52.   `user_lang` char(2) collate utf8_unicode_ci default NULL,
  53.   `se*` set('m','f') collate utf8_unicode_ci default NULL,
  54.   `birth_date` date default NULL,
  55.   `telephone` varchar(16) collate utf8_unicode_ci default NULL,
  56.   `mobile` varchar(16) collate utf8_unicode_ci default NULL,
  57.   `email` varchar(128) collate utf8_unicode_ci default NULL,
  58.   `user_icq` varchar(15) collate utf8_unicode_ci default NULL,
  59.   `user_msn` varchar(40) collate utf8_unicode_ci default NULL,
  60.   `user_skype` varchar(40) collate utf8_unicode_ci default NULL,
  61.   `webaddr` varchar(128) collate utf8_unicode_ci default NULL,
  62.   `addr` varchar(128) collate utf8_unicode_ci default NULL,
  63.   `city` varchar(64) collate utf8_unicode_ci default NULL,
  64.   `region` varchar(32) collate utf8_unicode_ci default NULL,
  65.   `country` char(2) collate utf8_unicode_ci default NULL,
  66.   `post_code` varchar(16) collate utf8_unicode_ci default NULL,
  67.   `is_email_public` smallint(6) default NULL,
  68.   `is_acct_active` smallint(6) default NULL,
  69.   `date_created` datetime default NULL,
  70.   `last_updated` datetime default NULL,
  71.   PRIMARY KEY  (`user_id`)
  72. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  73.  
  74. --
  75. -- Daten für Tabelle `users`
  76. --
  77.  
  78.  
  79. -- --------------------------------------------------------
  80.  
  81. --
  82. -- Tabellenstruktur für Tabelle `user_groups`
  83. --
  84.  
  85. CREATE TABLE IF NOT EXISTS `user_groups` (
  86.   `users_id` int(11) NOT NULL,
  87.   `groups_id` int(11) NOT NULL,
  88.   UNIQUE KEY `ug` (`users_id`,`groups_id`),
  89.   KEY `groups_id` (`groups_id`)
  90. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  91.  
  92. --
  93. -- Daten für Tabelle `user_groups`
  94. --
  95.  
  96.  
  97. --
  98. -- Constraints der exportierten Tabellen
  99. --
  100.  
  101. --
  102. -- Constraints der Tabelle `forum_user`
  103. --
  104. ALTER TABLE `forum_user`
  105.   ADD CONSTRAINT `forum_user_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
  106.  
  107. --
  108. -- Constraints der Tabelle `user_groups`
  109. --
  110. ALTER TABLE `user_groups`
  111.   ADD CONSTRAINT `user_groups_ibfk_4` FOREIGN KEY (`groups_id`) REFERENCES `groups` (`group_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  112.   ADD CONSTRAINT `user_groups_ibfk_3` FOREIGN KEY (`users_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dr.e.
Moderator


Anmeldedatum: 04.11.2007
Beiträge: 98

BeitragVerfasst am: Sa 15 Dez, 2007 13:56    Titel: Antworten mit Zitat

Hallo Slava,

Zitat:
wie würdest du an die Sache gehen?


Hatte gedacht, dass der Ansatz bereits angekommen ist, ich versuche es aber nochmal verständlich rüberzubringen:

Grundlage allen Handelns ist der TOP-Down-Approach. Dieser beschreibt, dass ich ein Teilsystem von oben her entwerfe. Das bedeutet, dass ich mir zunächst die API überlege, die ich später brauchen werde. Dazu müssen selbstverständlich alle möglichen Anforderungen an die API definiert sein. Um das am konkreten Beispiel machen zu können lege ich einfach mal ein paar Anforderungen fest:

- Erstellen, Bearbeiten und Löschen von Benutzern
- Erstellen, Bearbeiten und Löschen von Gruppen
- Erstellen, Bearbeiten und Löschen von Berechtigungen

Dabei sind 3 Arten von Objekten interessant:

- Benutzer
- Gruppe
- Rolle
- Berechtigung

Die API sieht nun vor, dass man eine zentrale Klasse "userManagementManager" hat, die einem eine zentrale API für das Handling der oben genannten Objekte bereitstellt. Diese muss Methoden haben, wie ich sie bereits weiter oben angeführt hab. Ein Auszug sei nochmal hier aufgeführt:

- getUserList()
- getUserByID()
- getGroupList()
- getGroupByID()

Für das Benutzer-Objekt sollte es dann die Methoden

- getGroup()
- getPermissions()
- ...

geben. Diese Methoden ermöglichen z.B. schon das Laden einer Mitgliederliste und das Laden eines Benutzers. In den Rollen stecken entsprechende Berechtigungen, die definieren, welche Funktionen ausgeführt werden. Um das nochmal implementierungstechnisch zu verdeutlichen, ein kleines Beispiel, das zeigt, wie man innerhalb einer Software solche Rechte prüft. Beispiel soll ein Menü sein:

Php:
  1. <?php
  2.  
  3. import('sites::forum::biz','userManagementManager');
  4. import('sites::forum::biz','forumManager');
  5.  
  6. class MenuController extends baseController
  7. {
  8.  
  9.    function MenuController(){
  10.    }
  11.  
  12.    function transformContent(){
  13.  
  14.       // UserManagementManager holen
  15.       $uMM = &$this->__getServiceObject('sites::forum::biz','userManagementManager');
  16.       $User = $uMM->getUserByID($_SESSION['UserID']);
  17.       $Permissions = &$User->getPermissions(); // Array von Permissions
  18.  
  19.       // Menu laden
  20.       $fM = &$this->__getServiceObject('sites::forum::biz','forumManager');
  21.       $Menu = $fM->loadMenu(); // Array von Menu-Punkten
  22.  
  23.       // Menu zusammenbauen
  24.       $Buffer = (string)'';
  25.       foreach($Menu as $MenuObject){
  26.             if($MenuObject->get('PermissionOnly') == true){
  27.                   if($Permissions[$MenuObject->get('PermissionKey')] == true){
  28.                         $Buffer .= $MenuObject->get('DisplayName').'<br />';
  29.                   }                  
  30.             }
  31.       }
  32.  
  33.       // Puffer in den Platzhalter des aktuellen Templates setzen
  34.       $this->setPlaceHolder('Menu',$Buffer);
  35.  
  36.    }
  37.  
  38. }
  39.  
  40. ?>

Programmablauf sollte soweit klar sein. Ich habe das aus einem vorhanden Controller eines Programmes kopiert und modifiziert, deswegen sind hier Methoden des APF's (siehe Footer) enthalten. Der Verständlichkeit sollte das aber keinen Abbruch tun. Die Funktionen im einzelnen:

- Zunächst wird eine Instanz des userManagementManagers geholt und dieser zum Laden des aktuellen Users und dessen Berechtigungen verwendet.
- Die Berechtigungen sind nichts anderes als eine Liste mit Schlüsseln und einem Wert (true|false|...), die im Programm ausgewertet werden können.
- In der Implementierung bin ich oben bereits davon ausgegangen, dass jeder Menüpunkt einen sog. Permission-Key hat, den ich hinterher in den Permissionsets verwenden kann und so den Quellcode nicht ändern muss. Man kann das aber auch etwas ungenerischer anstellen und z.B. ein Adminmenü komplett abiffen in dem man einfach fragt:

Php:
  1. <?php
  2.  
  3. if($Permissions['showAdminMenu'] == true){
  4.    ...
  5. }
  6.  
  7. ?>

- Das Menü wird zunächst in einem Puffer zusammengesetzt und dann in einen Platzhalter geschrieben damit es angezeigt wird (Templating).


Die Definition der API ist an dieser Stelle abgeschlossen und wir müssen uns um die interne Implementierung kümmern. Um das Ganze einfach aber doch generisch zu halten verwende ich für die Tabellen definition einfache FK-Beziehungen statt eigene Beziehungstabellen. Das sieht wie folgt aus:

- Tabelle Benutzer (mit allen Attributen des Benutzers)
- Taballe Gruppen
- Tabelle Rolle
- Tabelle Berechtigungen

Die Benutzertabelle hat jeweils (der Einfachheit wegen) einen Frendschlüssel auf die Rollen- und Gruppen-Tabelle, damit die Zuordnung zwischen Benutzer, Gruppe und Rolle geregelt ist. Die Berechtigungen-Tabelle beinhaltet die Berechtigungsdefinitionen in der Form KEY=VALUE, d.h. 3 Spalten:

- PermissionID
- PermissionKey
- PermussionValue
- PermissionRole

Die letzte Spalte ist die Referenz auf eine Rolle und damit kann ich mir ganz einfach die Permissions selektieren, die zu einem Benutzer gehören, da die Rollen-ID sowohl in der Benutzer-Tabelle, als auch in der Berechtigungstabelle vorhanden ist.

Das Design hat natürlich den Nachteil, dass einem Benutzer nur eine Gruppe und eine Rolle zugewiesen werden kann, was im täglichen Leben häufig zu Problemen wie Mehrfachdatenhaltung führt, weil Rollen - wenn sie sich auch nur um eine Permission unterscheiden - doppelt angelegt werden müssen. Davon sehe ich aber mal ab.

Um eine noch bessere Trennung zwischen eigentlicher Geschäftslogik und Datenhaltung erreichen zu können möchte ich eine weitere Klasse einführen: den userManagementMapper. Dieser soll die Daten (Objekte Benutzer, Gruppe, Rolle, ...) aus der Datenbank lesen und dem Manager zur Verfügung stellen. Das Beispiel des Ladens des Benutzers würde dann ungefähr wie folgt aussehen:

Php:
  1. <?php
  2.  
  3. import('sites::forum::data','userManagementMapper');
  4.  
  5. class userManagementManager extends coreObject
  6. {
  7.  
  8.    private $__UserCache = array();
  9.  
  10.  
  11.    function userManagementManager(){
  12.    }
  13.  
  14.    function getUserByID($UserID){
  15.  
  16.       if(isset($this->__UserCache[$UserID])){
  17.          return $this->__UserCache[$UserID];
  18.       }
  19.  
  20.       // Datenschicht-Komponente holen
  21.       $uMM = &$this->__getServiceObject('sites::forum::data','userManagementMapper');
  22.  
  23.       // Benutzer laden
  24.       $User = $uMM->loadUserByID($UserID);
  25.  
  26.       // Gruppe laden
  27.       $User->set('Group',$uMM->loadGroupByID($User->get('GroupID')));
  28.  
  29.       // Rolle laden
  30.       $User->set('Role',$uMM->loadRoleByID($User->get('RoleID')));
  31.  
  32.       // Benutzer in der Komponente Cachen
  33.       $this->__UserCache[$UserID] = $User;
  34.  
  35.       // Benutzer zurückgeben
  36.       return $User;
  37.  
  38.    }
  39.  
  40. }
  41.  
  42.  
  43. class userManagementMapper extends coreObject
  44. {
  45.  
  46.    function userManagementMapper(){
  47.    }
  48.  
  49.    function loadUserByID($UserID){
  50.    }
  51.  
  52.    function loadGroupByID($GroupID){
  53.  
  54.       // Statement erzeugen
  55.       $select = 'SELECT * FROM group WHERE group_id = \''.$GroupID.'\';';
  56.  
  57.       // Statement ausführen und Daten holen
  58.       $result = mysql_query($select);
  59.       $data = mysql_fetch_assoc($result);
  60.  
  61.       // Array in Objekt mappen und zurückgeben
  62.       return $this->__mapGroup2DomainObject($data);
  63.  
  64.    }
  65.  
  66.    function loadRoleByID($RoleID){
  67.    }
  68.  
  69.    private function __mapGroup2DomainObject($Result){
  70.  
  71.       // Gruppen-Objekt instanziieren
  72.       $Group = new Group();
  73.  
  74.       // Attribute setzen
  75.       $Group->set('ID',$Result['group_id']);
  76.       $Group->set('Name',$Result['name']);
  77.  
  78.       // Gefülltes Domain-Objekt zurückgeben
  79.       return $Group;
  80.  
  81.    }
  82.  
  83. }
  84.  
  85. ?>

Ich hoffe der Design-Ansatz wird nun ein wenig klarer. Wenn man eine Mehrfachzuordnung machen möchte, muss das Datenmodell noch weiter normalisiert werden. Hier empfiehlt sich, die Beziehungen in eigene Tabellen auszulagern und die Objektattribute in einer Tabelle zu halten. Aus der Beziehung zwischen Benutzer und Gruppe werden dann 3 Tabellen:

- Benutzer
- Beziehungstabelle
- Gruppe

Somit ist eine n:m-Beziehung einfach möglich und mit ein paar INNER JOINs lassen sich die Daten einfach selektieren.


_________________

Grüße,
Dr.E.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Have a look at www.adventure-php-framework.org!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    bituniverse.com Foren-Übersicht -> OFF-Topic und Sonstiges Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite Zurück  1, 2, 3, 4, 5  Weiter
Seite 4 von 5

 
Gehe zu:  
Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB2.de
Powered by WebRing.