Xuser
Inhaltsverzeichnis
xuser - Benutzerverwaltung
Das Kommando xuser dient zur Bearbeitung der Benutzer und der Benutzergruppe. Über die Benutzergruppen erfolgt die Rechtevergabe.
Benutzer
Unter dem Baumeintrag Benutzer werden die einzelnen Benutzer aufgelistet, deren Daten auf der entsprechenden Seite dann bearbeitet werden können.
In der Kategorie Benutzer werden die Stammdaten zum Benutzer angezeigt. Technisch relevant sind die ID und der Login-Name, während Kurz-, Vor- und Nachname keine technische Bedeutung haben. Üblicherweise wird der Passwort-Hash nicht direkt bearbeitet, sondern eine Neues Passwort im gleichnamigen Feld eingegeben, womit der Passwort-Hash generiert wird. In UseriD können die IDs auf vorherigen oder parallelen System eingegeben werden, in LDAP eine LDAP-ID.
In Explizite Gruppenzugehörigkeiten dieses Benutzers ist eine Liste der Benutzergruppen zu finden, in denen der Benutzer direkt enthalten ist. Der Benutzer ist dann auch implizit in allen diesen Gruppen übergeordneten Gruppen enthalten.
Schließlich können noch zu jedem User ToDos gespeichert werden.
Alphabetische Benutzergruppierung
Bei einer großen Zahl von Benutzern mag der Wunsch aufkommen, diese nach dem Anfangsbuchstaben ihres Login-Namens zu gruppieren.
Dazu wird in xuser_flt das Sub-Kommando xuser_open mit dem Parameter userc statt dem Parameter user aufgerufen.
#tree_add u=root c=$T(User) s="#page_fill d=xuser_page_users" o=xuser_open(userc)
Benutzergruppen
Benutzrerechte werden über Benutzergruppen zugewiesen. Diese Benutzergruppen sind in BAF hierarchisch organisiert. Hier im Beispiel ist die Gruppe user.admin eine Untergruppe der Gruppe user. Benutzer der Gruppe user.admin sind implizit auch Mitglied der Gruppe user, umgekehrt gilt das jedoch nicht.
Die hierarchische Organisation der Gruppen erfolgt über die Eigenschaft Path, diese stellt auch den Namen der Gruppe dar. In GroupID können die IDs aus vorherigen Systemen gespeichert werden, in LDAP die Gruppen-GUID in einem ActiveDirectory.
Hier im Beispiel ist der Benutzer example direkt, also explizit Mitglied der Gruppe. Dagegen ist der User admin implizit Mitglied der Gruppe, weil er explizit Mitglied einer Untergruppe ist.
Individualgruppen
Benutzerrechte können in BAF nur über Gruppen zugewiesen werden. Damit auch einem einzelnen Benutzer gezielt Rechte eingeräumt werden können, gibt es so genannte Individualgruppen. Diese enthalten im Regelfall nur einen einzigen Benutzer. Es ist aber möglich, weitere Benutzer aufzunehmen, zum Beispiel, um ihnen für eine Urlaubsvertretung entsprechende Rechte einzuräumen.
Um die Individualgruppen anzulegen, gehen Sie auf die entsprechende Seite und klicken auf den Button Individualgruppen aktualisieren. Beachten Sie, dass dabei nur neue Individualgruppen angelegt werden, aber nicht die Pfade von bestehenden geändert werden (weil die im Code referenziert sein könnten).
Tabellen
create table user_user( user_user_id varchar(40) not null primary key, login varchar(40) not null unique, password varchar(140) not null, shortname varchar(12), firstname varchar(40), lastname varchar(40), userid varchar(20), ldap varchar(40), email varchar(80), status int, datechg date, usrchg varchar(40), progchg varchar(40) );
create table user_group( user_group_id varchar(40) not null primary key, type char(1) not null, path varchar(400) not null unique, groupid varchar(20), ldap varchar(40), user_user_id varchar(40), status int, datechg date, usrchg varchar(40), progchg varchar(40) );
Die Tabelle user_user2group speichert, welcher Benutzer in welcher Gruppe explizit Mitglied ist.
create table user_user2group( user_user2group_id varchar(40) not null primary key, user_user_id varchar(40) not null, user_group_id varchar(40) not null, status int, datechg date, usrchg varchar(40), progchg varchar(40) );
Code
xuser
#rights n=frm r_user=r r_user.admin=w #rights n=admin r_user.admin=w #frm y=treepage c=xuser flt=xuser_flt w=300 #btn y=save s=#save se=c #btn y=cancel s=#cancel se=cp #btn y=back s=#treeback se=b #btn y=backback s=#treebackback se=b #btn c=$T(Refresh) se=b s=#filter w=100 #var_set n=link z=$CP(0) #filter
xuser ist vor allem die Formulardefinition und als solche ziemlich Standard. User haben Leserechte, Administratoren Schreibrechte. Wenn das Kommando mit Parameter aufgerufen wird, dann enthält dieser die User-ID, um gleich den entsprechenden User aufzurufen (zum Beispiel aus xtodo heraus). Zu diesem Zweck wird die erst mal in der Variablen link gespeichert.
xuser_add
~ $ICP(0,user) #tree_add u=sel c=$T(new_user) t=user_user s="#page_fill d=xuser_page_user" si=Y ~ $ICP(0,change_password) #page_val i=vl col=1 row=3 z=$HASH($PVAL(vl,1,2),SHA512) ~ $ICP(0,group) #tree_add u=sel c=$T(new_group) c1=path t=user_group s="#page_fill d=xuser_page_group" si=Y f_type=G f_user_group_id= ~ $ICP(0,user_in_group) #grd_add i=user_ex f_user_group_id=$PVAL(vl,1,0) f_status=1 ~ $ICP(0,group_in_user) #grd_add i=group_ex f_user_user_id=$PVAL(vl,1,0) f_status=1 ~ $ICP(0,upsert_igs) #sql select u.user_user_id, u.login #sql from user_user u #sql left outer join user_group g on g.type = 'I' and g.user_user_id = u.user_user_id #sql where u.status = 1 and g.user_group_id is null #opensql n=igs er=xuser_add_line(igs_ins) ~~
Das Kommando xuser_add fasst verschiedene kleine Routinen zusammen, nicht immer handelt es sich im strengen Sinn um Add-Operationen. Um die Aufrufe zu unterscheiden, wird der erste Parameter (Index 0) verwendet.
Bei den Parametern user, group, user_in_group und group_in_user werden dem entsprechenden Baum oder Grid-Segment ein Eintrag hinzugefügt.
Mit dem Parameter change_password aufgerufen wird die Eingabe aus der dritten Zeile (Index 2) gehasht und in die vierte Zeile (Index 3) geschrieben.
Sollen die Individualgruppen aktualisiert werden, so wird der Parameter upsert_igs verwendet. Mit dem SELECT-Statement werden User gesucht, für die es noch keine Individualgruppe gibt (die auf diesen User referenziert). Für alle diese User wird das Kommando xuser_add_line aufgerufen
xuser_add_line
~ $ICP(0,igs_ins) #upsert y=i t=user_group f_user_group_id=$GUID() f_type=I f_path="ig.$DATA(igs,login)" f_user_user_id=$DATA(igs,user_user_id) f_status=1 ~~
Wird bei der Aktualisierung der Individualgruppe von xuser_add(upsert_igs) aufgerufen und legt einfach nur einen entsprechenden Datensatz in user_group an. Das Feld type wird auf I gesetzt, dadurch ist es eine Individualgruppe.
xuser_flt
#tree_clear ~ $NEMPTY($VAR(link)) #sql select user_user_id, login, shortname from user_user where user_user_id = :kid #tree_node u=root t=user_user c1=login c2=shortname s="#page_fill d=xuser_page_user" #tree_fillsql fi=Y kid=$VAR(link) #tree_add u=root c=$T(Groups) s="#page_fill d=xuser_page_groups(G)" o=xuser_open(g) #tree_add u=root c=$T(Individual_groups) s="#page_fill d=xuser_page_groups(I)" o=xuser_open(ig) ~ #tree_add u=root c=ToDo s="#page_fill d=xtodo_page_todo(XU)" #tree_add u=root c=$T(User) s="#page_fill d=xuser_page_users" o=xuser_open(user) #tree_add u=root c=$T(Groups) s="#page_fill d=xuser_page_groups(G)" o=xuser_open(g) #tree_add u=root c=$T(Individual_groups) s="#page_fill d=xuser_page_groups(I)" o=xuser_open(ig) ~~
Wenn die Variable link nicht leer ist, dann werden die Daten des Users anhand der ID ermittelt.
Andernfalls werden lediglich die vier Top-Einträge des Baums geschrieben, User und Gruppen werden dann beim Öffnen der Nodes dynamisch nachgeladen. Abweichend dazu muss beim Baumeintrag ToDo nur xtodo_page_todo aufgerufen und als Parameter der Typ der ToDos mitgegeben werden, in diesem Fall also XU.
xuser_open
~ $ICP(0,user) #sql select user_user_id, login, shortname from user_user order by login #tree_node u=exp t=user_user c1=login c2=shortname s="#page_fill d=xuser_page_user" #filltreesql ~ $ICP(0,userc) #sql select upper(substr(login, 1, 1)) as lc, user_user_id, login, shortname from user_user order by login #tree_node u=exp k=lc c1=lc nc=Y s="#page_fill d=xuser_page_users" #tree_node u=last t=user_user c1=login c2=shortname s="#page_fill d=xuser_page_user" #filltreesql ~ $ICP(0,g) #sql select g.* from user_group g where g.type = 'G' order by path #tree_node u=exp t=user_group c1=path s="#page_fill d=xuser_page_group(G)" #filltreepath t=user_group pn=path ~ $ICP(0,ig) #sql select g.user_group_id, g.path, u.firstname || ' ' || u.lastname as user from user_group g #sql left outer join user_user u on u.user_user_id = g.user_user_id where g.type = 'I' #tree_node u=exp t=user_group c1=path c2=user s="#page_fill d=xuser_page_group(I)" #filltreesql ~ $ICP(0,igc) #sql select upper(substr(u.login, 1, 1)) as lc, g.user_group_id, g.path, u.firstname || ' ' || u.lastname as user from user_group g #sql left outer join user_user u on u.user_user_id = g.user_user_id where g.type = 'I' #tree_node u=exp k=lc c1=lc nc=Y s="#page_fill d=xuser_page_groups(IC)" #tree_node u=last t=user_group c1=path c2=user s="#page_fill d=xuser_page_group(I)" #filltreesql ~~
Je nach Parameter werden die User, die Gruppen (g) oder die Individualgruppen (ig) geöffnet. Es werden den sehr "geradeaus" die entsprechenden Datensätze angezeigt.
Erwähnung verdienen die Parameter userc und igc. Bei einer großen Anzahl von Usern wird der Baum schnell unübersichtlich. Mit diesen Parametern werden die Datensätze nach dem ersten Buchstaben der Benutzernamens gruppiert, siehe Screenshot oben auf der Seite.
xuser_page_group
Wegen der Länge besprechen wir diese Seite in Abschnitten.
#page #prim as=Y #cat as=Y c=$T(Group) #btns_seg cnd=$IPP(0,G) #btns_btn c=$T(Add_sub_group) w=180 cmd=xuser_add(group) cnd=$IPP(0,G) #vl_seg cc=2 clt=ss w1=100 w2=300 wst2=300 w3=60 w4=60 n=vl c=" " b=H #vl_line c1="ID" f2=user_group_id ro=Y nvic2=$GUID() r=admin #vl_line c1="Type" f2=type ro=Y y2=lookup ld2=user_group_type nv2=$FND(s,type) #vl_line c1="Path" f2=path nv2=$FND(s,path). #vl_line c1="Groupid" f2=groupid #vl_line c1="Ldap" f2=ldap #vl_line c1="User" f2=user_user_id ro=Y y2=lookup ls2=system_user_all cnd=$ICP(0,I) #vl_line c1="Status" f2=status y2=lookup ld2=general_status nv2=1 #sql select * from user_group where user_group_id = :kid #vl_data q=sql t=user_group kid=$FND(s,user_group_id)
Zunächst haben wir hier ziemlich "geradeaus" die Darstellung des entsprechenden Datensatzes in der Tabelle user_group, davor einen Button zum Einfügen einer Untergruppe. Untergruppen brauchen wir nicht bei Individualgruppen, darum werden für das Button-Segment und den Button eine entsprechende condition (cnd) gesetzt.
Ein paar Details können dennoch erläutert werden. In der Zeile ID haben wir die Anweisung nvic2=$GUID(). Haben wir in der zweiten Spalte keinen Wert (nv - Null Value), handelt es sich also um eine neue Gruppe, dann wird dort eine GUID eingefügt. Ist dies der Fall, dann wird gleichzeitig der Datensatz als inserted (i) und als changed (c) gekennzeichnet. (Das mit den changed ist erforderlich, um das Hinzufügen einer Gruppe sofort durch den Cancel-Button abbrechen zu können, denn die Buttons #save und #cancel sind erst dann verfügbar, wenn eine Änderung vorgenommen wurde.)
Der Typ wird aus dem Baum gezogen (nv2=$FND(s,type)), das entsprechende Feld wird in xuser_add gesetzt. Der Pfad wird mit dem Pfad der übergeordneten Gruppe vorbelegt und kann dann entsprechend ergänzt werden.
Die Zeile User benötigen wir nur bei Individualgruppen, also wird eine entsprechende condition (cnd) gesetzt.
#prim as=Y #cat as=Y c=$T(User_in_group_explicite) #btns_seg #btns_btn c=$T(Add_user2group) w=250 cmd=xuser_add(user_in_group) #grd_seg frc=0 fcc=1 clt=ss n=user_ex c=" " b=H #grd_col f=user_user2group_id c1="ID" w=30 y=guid ro=Y nvi=$GUID() #grd_col f=user_user_id c1=$T(User) w=300 y=lookup ls=system_user_all #grd_col f=user_group_id c1="User Group Id" w=0 ro=Y #grd_col f=status c1="Status" w=120 y=lookup ld=general_status #sql select * from user_user2group where user_group_id = :kid #grd_data q=sql t=user_user2group kid=$PVAL(vl,1,0)
In der nächsten Primärregion haben wir die expliziten Gruppenzugehörigkeiten der Gruppe inklusive der Möglichkeit, weitere Benutzer hinzuzufügen. Das ist sehr "geradeaus" Daten aus einer Detail-Tabelle auf den Index der Haupttabelle zu filtern und in einem Grid anzuzeigen. Die ID selbst holen wir mit der Funktion $PVAL aus dem VL-Segment.
#prim as=Y #cat as=Y c=$T(User_in_group_all) #grd_seg frc=0 fcc=1 clt=ss n=user_all ro=Y #grd_col f=user_user2group_id c1="ID" w=30 y=guid #grd_col f=path c1="Path" w=200 wst=200 #grd_col f=user_user_id c1=$T(User) w=200 wst=500 y=lookup ls=system_user_all #grd_col f=status c1="Status" w=80 y=lookup ld=general_status #sql select z.user_user2group_id, g.path, z.user_user_id, g.status #sql from user_user2group z #sql inner join user_group g on g.user_group_id = z.user_group_id and g.path like :kpath #sql order by path #grd_data q=sql kpath=$PVAL(vl,1,2)%
In der letzten Primärregion haben wir alle Benutzer der Gruppe gelistet, auch diejenigen, die Mitglieder von Untergruppen sind. Den Pfad der Gruppe holen wir wieder mit der Funktion $PVAL aus dem VL-Segment. Da wir auch alle untergeordneten Gruppen haben wollen, wird hier ein %-Zeichen als SQL-Jokerzeichen ergänzt.