Xuser

Aus bafbal.de
Zur Navigation springen Zur Suche springen

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.

Die Benutzerseite

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.

Benutzer nach Anfangsbuchstaben gruppiert

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.

Eine Benutzergruppe

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.

Individualgruppen anlegen

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.