Add user list

merge-requests/6/head
meskio 5 years ago
parent 8c1de52f9f
commit 93d61e86ed
Signed by: meskio
GPG Key ID: 52B8F5AC97A2DA86
  1. 4
      examples/data.ldif
  2. 47
      ldap/user.go
  3. 32
      ldap/user_test.go
  4. 22
      server/server.go
  5. 27
      tmpl/users.html

@ -31,8 +31,8 @@ objectClass: account
objectClass: posixAccount
userPassword: {SSHA}FHqod3gytvH9MDGhpMV1DKjyU7eO1EDG
loginShell: /bin/bash
uidNumber: 1000
gidNumber: 1000
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/sindominio/superuser
gecos: SuperUser,,,,Calanda

@ -4,10 +4,21 @@ import (
"errors"
"fmt"
"log"
"strconv"
"github.com/go-ldap/ldap"
)
//User has the ldap data of the user
type User struct {
DN string
Name string
Shell string
UID int
GID int
Home string
}
// ValidateUser in the ldap
func (l *Ldap) ValidateUser(user string, pass string) error {
conn, err := l.login(user, pass)
@ -35,6 +46,42 @@ func (l *Ldap) ChangePass(user string, oldpass string, newpass string) error {
return err
}
//ListUsers returns a list of usernames
func (l *Ldap) ListUsers() ([]User, error) {
conn, err := l.connect()
if err != nil {
return nil, err
}
defer conn.Close()
searchRequest := ldap.NewSearchRequest(
"ou=people,"+l.DC,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=posixAccount))",
[]string{"dn", "uid", "uidNumber", "gidNumber", "loginShell", "homeDirectory"},
nil,
)
sr, err := conn.Search(searchRequest)
if err != nil {
return nil, err
}
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"),
})
}
return users, nil
}
func (l *Ldap) login(user string, password string) (*ldap.Conn, error) {
conn, err := l.connect()
if err != nil {

@ -55,3 +55,35 @@ func TestChangePassRO(t *testing.T) {
t.Errorf("ValidateUser() didn't fail to auth the user")
}
}
func TestListUsers(t *testing.T) {
l := testLdap()
userCount := 0
users, err := l.ListUsers()
if err != nil {
t.Errorf("ListUsers() failed: %v", err)
}
for _, user := range users {
if user.Name == "user" {
userCount++
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)
}
}
if user.Name == "superuser" {
userCount++
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)
}
}
}
if userCount != 2 {
t.Errorf("Not the righ number of users: %v", users)
}
}

@ -2,6 +2,7 @@ package server
import (
"html/template"
"log"
"net/http"
"0xacab.org/sindominio/lowry/ldap"
@ -15,6 +16,7 @@ var tmpl = template.Must(template.ParseFiles(
"tmpl/login.html",
"tmpl/index.html",
"tmpl/password.html",
"tmpl/users.html",
))
type server struct {
@ -33,6 +35,7 @@ func Serve(addr string, l *ldap.Ldap) error {
r.HandleFunc("/login/", s.loginHandler)
r.HandleFunc("/logout/", s.logoutHandler).Methods("POST")
r.HandleFunc("/password/", s.passwordHandler)
r.HandleFunc("/users/", s.usersHandler)
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") })
@ -101,6 +104,25 @@ func (s *server) passwordHandler(w http.ResponseWriter, r *http.Request) {
}
}
func (s *server) usersHandler(w http.ResponseWriter, r *http.Request) {
session := s.sess.get(w, r)
if session == nil || !s.isAdmin(session.user) {
log.Println("Non admin attemp to list users")
http.NotFound(w, r)
return
}
users, err := s.ldap.ListUsers()
if err != nil {
log.Println("An error ocurred retrieving user list: ", err)
http.NotFound(w, r)
return
}
if err = tmpl.ExecuteTemplate(w, "users.html", users); err != nil {
log.Println("An error ocurred loading user list: ", err)
}
}
func (s *server) isAdmin(user string) bool {
return s.ldap.InGroup(user, "adm")
}

@ -0,0 +1,27 @@
{{template "header.html"}}
{{template "navbar.html" "users"}}
<table class="table">
<thead>
<tr>
<th scope="col">Nombre</th>
<th scope="col">Shell</th>
<th scope="col">Home</th>
<th scope="col">UID</th>
<th scope="col">GID</th>
</tr>
</thead>
<tbody>
{{range .}}
<tr {{if ne .Shell "/bin/false"}}class="table-success"{{end}}>
<th scope="row">{{.Name}}</th>
<td>{{.Shell}}</td>
<td>{{.Home}}</td>
<td>{{.UID}}</td>
<td>{{.GID}}</td>
</tr>
{{end}}
</tbody>
</table>
{{template "footer.html"}}
Loading…
Cancel
Save