Add/remove from groups

This commit is contained in:
Alex Auvolat 2020-02-09 22:32:59 +01:00
parent 43825b1bbc
commit db9840a6f1
2 changed files with 183 additions and 51 deletions

142
admin.go
View File

@ -123,12 +123,19 @@ func handleAdminGroups(w http.ResponseWriter, r *http.Request) {
type AdminLDAPTplData struct { type AdminLDAPTplData struct {
DN string DN string
Members []string Members []EntryName
Groups []string Groups []EntryName
Props map[string]*PropValues Props map[string]*PropValues
Children []Child Children []Child
Path []PathItem Path []PathItem
AddError string
Error string
Success bool
}
type EntryName struct {
DN string
DisplayName string
} }
type Child struct { type Child struct {
@ -146,8 +153,6 @@ type PathItem struct {
type PropValues struct { type PropValues struct {
Values []string Values []string
Editable bool Editable bool
ModifySuccess bool
ModifyError string
} }
func handleAdminLDAP(w http.ResponseWriter, r *http.Request) { func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
@ -160,10 +165,8 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
dn := mux.Vars(r)["dn"] dn := mux.Vars(r)["dn"]
modifyAttr := "" dError := ""
modifyError := "" dSuccess := false
modifySuccess := false
addError := ""
if r.Method == "POST" { if r.Method == "POST" {
r.ParseForm() r.ParseForm()
@ -179,18 +182,17 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
} }
} }
modifyAttr = attr
if len(values_filtered) == 0 { if len(values_filtered) == 0 {
modifyError = "Refusing to delete attribute." dError = "Refusing to delete attribute."
} else { } else {
modify_request := ldap.NewModifyRequest(dn, nil) modify_request := ldap.NewModifyRequest(dn, nil)
modify_request.Replace(attr, values_filtered) modify_request.Replace(attr, values_filtered)
err := login.conn.Modify(modify_request) err := login.conn.Modify(modify_request)
if err != nil { if err != nil {
modifyError = err.Error() dError = err.Error()
} else { } else {
modifySuccess = true dSuccess = true
} }
} }
} else if action == "add" { } else if action == "add" {
@ -208,9 +210,10 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
modify_request.Add(attr, values_filtered) modify_request.Add(attr, values_filtered)
err := login.conn.Modify(modify_request) err := login.conn.Modify(modify_request)
modifyAttr = attr
if err != nil { if err != nil {
addError = err.Error() dError = err.Error()
} else {
dSuccess = true
} }
} else if action == "delete" { } else if action == "delete" {
attr := strings.Join(r.Form["attr"], "") attr := strings.Join(r.Form["attr"], "")
@ -220,7 +223,42 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
err := login.conn.Modify(modify_request) err := login.conn.Modify(modify_request)
if err != nil { if err != nil {
modifyError = err.Error() dError = err.Error()
} else {
dSuccess = true
}
} else if action == "delete-from-group" {
group := strings.Join(r.Form["group"], "")
modify_request := ldap.NewModifyRequest(group, nil)
modify_request.Delete("member", []string{dn})
err := login.conn.Modify(modify_request)
if err != nil {
dError = err.Error()
} else {
dSuccess = true
}
} else if action == "add-to-group" {
group := strings.Join(r.Form["group"], "")
modify_request := ldap.NewModifyRequest(group, nil)
modify_request.Add("member", []string{dn})
err := login.conn.Modify(modify_request)
if err != nil {
dError = err.Error()
} else {
dSuccess = true
}
} else if action == "delete-member" {
member := strings.Join(r.Form["member"], "")
modify_request := ldap.NewModifyRequest(dn, nil)
modify_request.Delete("member", []string{member})
err := login.conn.Modify(modify_request)
if err != nil {
dError = err.Error()
} else {
dSuccess = true
} }
} }
} }
@ -282,33 +320,76 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
break break
} }
} }
pv := &PropValues{ props[attr.Name] = &PropValues{
Values: attr.Values, Values: attr.Values,
Editable: editable, Editable: editable,
} }
if attr.Name == modifyAttr {
if modifySuccess {
pv.ModifySuccess = true
} else if modifyError != "" {
pv.ModifyError = modifyError
}
}
props[attr.Name] = pv
} }
} }
} }
members := []string{} members_dn := []string{}
if mp, ok := props["member"]; ok { if mp, ok := props["member"]; ok {
members = mp.Values members_dn = mp.Values
delete(props, "member") delete(props, "member")
} }
groups := []string{}
members := []EntryName{}
if len(members_dn) > 0 {
mapDnToName := make(map[string]string)
searchRequest = ldap.NewSearchRequest(
config.UserBaseDN,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(objectClass=organizationalPerson)"),
[]string{"dn", "displayname"},
nil)
sr, err := login.conn.Search(searchRequest)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for _, ent := range sr.Entries {
mapDnToName[ent.DN] = ent.GetAttributeValue("displayname")
}
for _, memdn := range members_dn {
members = append(members, EntryName{
DN: memdn,
DisplayName: mapDnToName[memdn],
})
}
}
groups_dn := []string{}
if gp, ok := props["memberof"]; ok { if gp, ok := props["memberof"]; ok {
groups = gp.Values groups_dn = gp.Values
delete(props, "memberof") delete(props, "memberof")
} }
groups := []EntryName{}
if len(groups_dn) > 0 {
mapDnToName := make(map[string]string)
searchRequest = ldap.NewSearchRequest(
config.GroupBaseDN,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(objectClass=groupOfNames)"),
[]string{"dn", "displayname"},
nil)
sr, err := login.conn.Search(searchRequest)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for _, ent := range sr.Entries {
mapDnToName[ent.DN] = ent.GetAttributeValue("displayname")
}
for _, grpdn := range groups_dn {
groups = append(groups, EntryName{
DN: grpdn,
DisplayName: mapDnToName[grpdn],
})
}
}
// Get children // Get children
searchRequest = ldap.NewSearchRequest( searchRequest = ldap.NewSearchRequest(
dn, dn,
@ -341,6 +422,7 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
Props: props, Props: props,
Children: children, Children: children,
Path: path, Path: path,
AddError: addError, Error: dError,
Success: dSuccess,
}) })
} }

View File

@ -36,6 +36,16 @@
</tbody> </tbody>
</table> </table>
{{if .Success}}
<div class="alert alert-success mt-2">Modification enregistrée.</div>
{{end}}
{{if .Error}}
<div class="alert alert-danger mt-2">
Impossible d'effectuer la modification.
<div style="font-size: 0.8em">{{.Error}}</div>
</div>
{{end}}
<h5>Attributs</h5> <h5>Attributs</h5>
<div class="container"> <div class="container">
{{range $key, $value := .Props}} {{range $key, $value := .Props}}
@ -54,15 +64,6 @@
</div> </div>
</div> </div>
</form> </form>
{{if $value.ModifySuccess}}
<div class="alert alert-success mt-2">Modification enregistrée.</div>
{{end}}
{{if $value.ModifyError}}
<div class="alert alert-danger mt-2">
Impossible de modifier la valeur.
<div style="font-size: 0.8em">{{$value.ModifyError}}</div>
</div>
{{end}}
</div> </div>
<div class="col-md-1"> <div class="col-md-1">
@ -94,12 +95,6 @@
<input class="form-control" type="text" name="attr" placeholder="Ajouter un attribut..." /> <input class="form-control" type="text" name="attr" placeholder="Ajouter un attribut..." />
</div> </div>
<div class="col-md-7"> <div class="col-md-7">
{{if .AddError}}
<div class="alert alert-danger">
Impossible d'ajouter la valeur.
<div style="font-size: 0.8em">{{.AddError}}</div>
</div>
{{end}}
<div class="form-row"> <div class="form-row">
<textarea name="values" placeholder="Valeur(s)..." rows="2" class="form-control col-md-9"></textarea> <textarea name="values" placeholder="Valeur(s)..." rows="2" class="form-control col-md-9"></textarea>
<div class="col-md-3"> <div class="col-md-3">
@ -112,21 +107,76 @@
</div> </div>
{{if .Members}} {{if .Members}}
<hr class="mt-4" />
<h5 class="mt-4">Membres</h5> <h5 class="mt-4">Membres</h5>
<ul class="list-group"> <div class="container">
{{range .Members}} {{range .Members}}
<li class="list-group-item">{{.}}</li> <div class="row mt-4">
<div class="col-md-3">
<strong>{{.DisplayName}}</strong>
</div>
<div class="col-md-5">
<a href="/admin/ldap/{{.DN}}">{{.DN}}</a>
</div>
<div class="col-md-2">
<form method="POST" onsubmit="return confirm('Supprimer du groupe ?');">
<input type="hidden" name="action" value="delete-member" />
<input type="hidden" name="member" value="{{.DN}}" />
<input type="submit" value="Supprimer" class="form-control btn btn-danger btn-sm" />
</form>
</div>
</div>
{{end}} {{end}}
</ul> <form method="POST">
<input type="hidden" name="action" value="add" />
<input type="hidden" name="attr" value="member" />
<div class="row mt-4">
<div class="col-md-3"><strong>Ajouter au groupe :</strong>
</div>
<div class="col-md-5">
<input class="form-control" type="text" name="values" placeholder="Groupe..." />
</div>
<div class="col-md-2">
<input type="submit" value="Ajouter" class="form-control btn btn-success btn-sm" />
</div>
</form>
</div>
{{end}} {{end}}
{{if .Groups}} {{if .Groups}}
<hr class="mt-4" />
<h5 class="mt-4">Membre de</h5> <h5 class="mt-4">Membre de</h5>
<ul class="list-group"> <div class="container">
{{range .Groups}} {{range .Groups}}
<li class="list-group-item">{{.}}</li> <div class="row mt-4">
<div class="col-md-3">
<strong>{{.DisplayName}}</strong>
</div>
<div class="col-md-5">
<a href="/admin/ldap/{{.DN}}">{{.DN}}</a>
</div>
<div class="col-md-2">
<form method="POST" onsubmit="return confirm('Supprimer du groupe ?');">
<input type="hidden" name="action" value="delete-from-group" />
<input type="hidden" name="group" value="{{.DN}}" />
<input type="submit" value="Supprimer" class="form-control btn btn-danger btn-sm" />
</form>
</div>
</div>
{{end}} {{end}}
</ul> <form method="POST">
<input type="hidden" name="action" value="add-to-group" />
<div class="row mt-4">
<div class="col-md-3"><strong>Nouveau groupe :</strong>
</div>
<div class="col-md-5">
<input class="form-control" type="text" name="group" placeholder="Groupe..." />
</div>
<div class="col-md-2">
<input type="submit" value="Ajouter" class="form-control btn btn-success btn-sm" />
</div>
</form>
</div>
{{end}} {{end}}
<hr class="mt-4" /> <hr class="mt-4" />