Display single user information

merge-requests/6/head
meskio 5 years ago
parent 93d61e86ed
commit 67c9d94f4d
Signed by: meskio
GPG Key ID: 52B8F5AC97A2DA86
  1. 43
      ldap/user.go
  2. 26
      ldap/user_test.go
  3. 23
      server/server.go
  4. 14
      tmpl/user.html
  5. 2
      tmpl/users.html

@ -46,7 +46,22 @@ func (l *Ldap) ChangePass(user string, oldpass string, newpass string) error {
return err
}
//ListUsers returns a list of usernames
//GetUser returns the user data
func (l *Ldap) GetUser(name string) (User, error) {
conn, err := l.connect()
if err != nil {
return User{}, err
}
defer conn.Close()
entry, err := l.searchUser(name, conn)
if err != nil {
return User{}, err
}
return newUser(entry), nil
}
//ListUsers returns a list of all users in the ldap
func (l *Ldap) ListUsers() ([]User, error) {
conn, err := l.connect()
if err != nil {
@ -68,16 +83,7 @@ func (l *Ldap) ListUsers() ([]User, error) {
users := []User{}
for _, entry := range sr.Entries {
uid, _ := strconv.Atoi(entry.GetAttributeValue("uidNumber"))
gid, _ := strconv.Atoi(entry.GetAttributeValue("gidNumber"))
users = append(users, User{
DN: entry.DN,
Name: entry.GetAttributeValue("uid"),
Shell: entry.GetAttributeValue("loginShell"),
UID: uid,
GID: gid,
Home: entry.GetAttributeValue("homeDirectory"),
})
users = append(users, newUser(entry))
}
return users, nil
}
@ -101,7 +107,7 @@ func (l *Ldap) searchUser(user string, conn *ldap.Conn) (entry *ldap.Entry, err
"ou=people,"+l.DC,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=posixAccount)(uid=%s))", ldap.EscapeFilter(user)),
[]string{"dn"},
[]string{"dn", "uid", "uidNumber", "gidNumber", "loginShell", "homeDirectory"},
nil,
)
sr, err := conn.Search(searchRequest)
@ -119,3 +125,16 @@ func (l *Ldap) searchUser(user string, conn *ldap.Conn) (entry *ldap.Entry, err
return entry, errors.New("More than one user found!!!")
}
}
func newUser(entry *ldap.Entry) User {
uid, _ := strconv.Atoi(entry.GetAttributeValue("uidNumber"))
gid, _ := strconv.Atoi(entry.GetAttributeValue("gidNumber"))
return User{
DN: entry.DN,
Name: entry.GetAttributeValue("uid"),
Shell: entry.GetAttributeValue("loginShell"),
UID: uid,
GID: gid,
Home: entry.GetAttributeValue("homeDirectory"),
}
}

@ -56,6 +56,32 @@ func TestChangePassRO(t *testing.T) {
}
}
func TestGetUser(t *testing.T) {
l := testLdap()
user, err := l.GetUser("user")
if err != nil {
t.Errorf("GetUsers(\"user\") failed: %v", err)
}
if user.UID != 1000 {
t.Errorf("Expected 1000 found: %v", user.UID)
}
if user.Shell != "/bin/bash" {
t.Errorf("Expected /bin/bash found: %v", user.Shell)
}
user, err = l.GetUser("superuser")
if err != nil {
t.Errorf("GetUsers(\"superuser\") failed: %v", err)
}
if user.UID != 1001 {
t.Errorf("Expected 1001 found: %v", user.UID)
}
if user.Shell != "/bin/bash" {
t.Errorf("Expected /bin/bash found: %v", user.Shell)
}
}
func TestListUsers(t *testing.T) {
l := testLdap()
userCount := 0

@ -16,6 +16,7 @@ var tmpl = template.Must(template.ParseFiles(
"tmpl/login.html",
"tmpl/index.html",
"tmpl/password.html",
"tmpl/user.html",
"tmpl/users.html",
))
@ -36,6 +37,7 @@ func Serve(addr string, l *ldap.Ldap) error {
r.HandleFunc("/logout/", s.logoutHandler).Methods("POST")
r.HandleFunc("/password/", s.passwordHandler)
r.HandleFunc("/users/", s.usersHandler)
r.HandleFunc("/users/{name}", s.userHandler)
r.HandleFunc("/bundle.js", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "dist/bundle.js") })
r.HandleFunc("/style.css", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "dist/style.css") })
@ -123,6 +125,27 @@ func (s *server) usersHandler(w http.ResponseWriter, r *http.Request) {
}
}
func (s *server) userHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userName := vars["name"]
session := s.sess.get(w, r)
if session == nil || (!s.isAdmin(session.user) && userName != session.user) {
log.Println("Non admin attemp to list users")
http.NotFound(w, r)
return
}
user, err := s.ldap.GetUser(userName)
if err != nil {
log.Println("An error ocurred retrieving user '", userName, "': ", err)
http.NotFound(w, r)
return
}
if err = tmpl.ExecuteTemplate(w, "user.html", user); err != nil {
log.Println("An error ocurred loading user: ", err)
}
}
func (s *server) isAdmin(user string) bool {
return s.ldap.InGroup(user, "adm")
}

@ -0,0 +1,14 @@
{{template "header.html"}}
{{template "navbar.html" "users"}}
<div class="row justify-content-center">
<dl>
<dt>Nombre</dt><dd>{{.Name}}</dd>
<dt>Shell</dt><dd>{{.Shell}}</dd>
<dt>Home</dt><dd>{{.Home}}</dd>
<dt>UID</dt><dd>{{.UID}}</dd>
<dt>GID</dt><dd>{{.GID}}</dd>
</dl>
</div>
{{template "footer.html"}}

@ -14,7 +14,7 @@
<tbody>
{{range .}}
<tr {{if ne .Shell "/bin/false"}}class="table-success"{{end}}>
<th scope="row">{{.Name}}</th>
<th scope="row"><a href="/users/{{.Name}}">{{.Name}}</a></th>
<td>{{.Shell}}</td>
<td>{{.Home}}</td>
<td>{{.UID}}</td>

Loading…
Cancel
Save