1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
# 30dec24 Software Lab. Alexander Burger
# *Salt *Login *Users *Perms
# crypt(3) algorithm, e.g. (setq *Salt (16 . "$6$@1$"))
(de passwd (Str Salt)
(if *Salt
(native "libcrypt.so" "crypt" 'S Str (or Salt (salt)))
Str ) )
(de salt ()
(text (cdr *Salt) (randpw (car *Salt))) )
(de randpw (Len)
(make
(in "/dev/urandom"
(do Len
(link
(get
'`(mapcar char
(conc
(range (char ".") (char "9"))
(range (char "A") (char "Z"))
(range (char "a") (char "z")) ) )
(inc (& 63 (rd 1))) ) ) ) ) ) )
(de auth (Nm Pw Cls)
(with (db 'nm (or Cls '+User) Nm)
(and
(: pw 0)
(= @ (passwd Pw @))
This ) ) )
### Login ###
(de login (Nm Pw Cls)
(ifn (setq *Login (auth Nm Pw Cls))
(msg *Pid " ? " Nm)
(msg *Pid " * " (stamp) " " Nm)
(tell 'hi *Pid Nm *Adr)
(push1 '*Bye '(logout))
(when *Timeout
(timeout (setq *Timeout `(* 3600 1000))) ) )
*Login )
(de logout ()
(when *Login
(rollback)
(off *Login)
(tell 'hi *Pid)
(msg *Pid " / " (stamp))
(when *Timeout
(timeout (setq *Timeout `(* 300 1000))) ) ) )
(de hi (Pid Nm Adr)
(if (and Nm (= Nm (; *Login nm)) (= Adr *Adr))
(bye)
(hi2 Pid Nm)
(tell 'hi2 *Pid (; *Login nm)) ) )
(de hi2 (Pid Nm)
(if2 Nm (lup *Users Pid)
(con @ Nm)
(idx '*Users (cons Pid Nm) T)
(idx '*Users @ NIL) ) )
### Role ###
(class +Role +Entity)
(rel nm (+Need +Key +String)) # Role name
(rel perm (+List +Symbol)) # Permission list
(rel usr (+List +Joint) role (+User)) # Associated users
(allow "@lib/role.l")
(dm url> (Tab)
(and (may RoleAdmin) (list "@lib/role.l" '*ID This)) )
### User ###
(class +User +Entity)
(rel nm (+Need +Key +String)) # User name
(rel pw (+Swap +String)) # Password
(rel role (+Joint) usr (+Role)) # User role
(rel nam (+String)) # Full Name
(rel tel (+String)) # Phone
(rel em (+String)) # E-Mail
(allow "@lib/user.l")
(dm url> (Tab)
(and
(or (may UserAdmin) (== *Login This))
(list "@lib/user.l" '*ID This) ) )
(dm gui> (This)
(<grid> 2
,"Full Name" (gui '(+E/R +TextField) '(nam : home obj) 40)
,"Phone" (gui '(+E/R +TelField) '(tel : home obj) 40)
,"E-Mail" (gui '(+E/R +MailField) '(em : home obj) 40) ) )
(dm login> ())
### Permission management ###
(de permission Lst
(while Lst
(queue '*Perms (car Lst))
(def (++ Lst) (++ Lst)) ) )
(de may Args
(mmeq Args (; *Login role perm)) )
(de must Args
(unless
(if (cdr Args)
(find
'((X)
(if (atom X)
(memq X (; *Login role perm))
(eval X) ) )
@ )
*Login )
(forbidden (car Args)) ) )
### GUI ###
(de choUser (Dst)
(choDlg Dst ,"Users" '(nm +User)) )
(de loginForm "Opt"
(form NIL
(when "Opt"
(eval (car "Opt"))
(----) )
(<grid> 2
,"Name" (gui 'nm '(+Focus +Able +TextField) '(not *Login) 20)
,"Password" (gui 'pw '(+Able +PwField) '(not *Login) 20) )
(--)
(gui '(+Button) '(if *Login ,"logout" ,"login")
'(cond
(*Login (post (logout)))
((login (val> (: home nm)) (val> (: home pw)))
(post
(clr> (: home pw))
(login> *Login) ) )
(T (error ,"Permission denied")) ) )
(when *Login
(<nbsp> 4)
(<span> "bold green"
(ht:Prin "'" (; *Login nm) ,"' logged in") ) )
(when "Opt"
(----)
(htPrin (cdr "Opt")) ) ) )
(class +PasswdField +E/R +Fmt +TextField)
(dm T @
(pass super
'(pw : home obj)
'((V) (and V "****"))
'((V)
(if (= V "****")
(: home obj pw 0)
(passwd V (: home obj pw 0)) ) ) ) )
|