Profile modify
This commit is contained in:
parent
ebb7553cc8
commit
6297981c3b
3 changed files with 181 additions and 11 deletions
122
main.go
122
main.go
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
@ -92,6 +93,7 @@ func main() {
|
||||||
|
|
||||||
http.HandleFunc("/", handleHome)
|
http.HandleFunc("/", handleHome)
|
||||||
http.HandleFunc("/logout", handleLogout)
|
http.HandleFunc("/logout", handleLogout)
|
||||||
|
http.HandleFunc("/profile", handleProfile)
|
||||||
|
|
||||||
staticfiles := http.FileServer(http.Dir("static"))
|
staticfiles := http.FileServer(http.Dir("static"))
|
||||||
http.Handle("/static/", http.StripPrefix("/static/", staticfiles))
|
http.Handle("/static/", http.StripPrefix("/static/", staticfiles))
|
||||||
|
@ -108,6 +110,12 @@ type LoginInfo struct {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LoginStatus struct {
|
||||||
|
Info *LoginInfo
|
||||||
|
conn *ldap.Conn
|
||||||
|
UserEntry *ldap.Entry
|
||||||
|
}
|
||||||
|
|
||||||
func logRequest(handler http.Handler) http.Handler {
|
func logRequest(handler http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
|
log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
|
||||||
|
@ -115,7 +123,7 @@ func logRequest(handler http.Handler) http.Handler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
|
func checkLogin(w http.ResponseWriter, r *http.Request) *LoginStatus {
|
||||||
session, err := store.Get(r, SESSION_NAME)
|
session, err := store.Get(r, SESSION_NAME)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
@ -125,14 +133,62 @@ func checkLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
|
||||||
username, ok := session.Values["login_username"]
|
username, ok := session.Values["login_username"]
|
||||||
password, ok2 := session.Values["login_password"]
|
password, ok2 := session.Values["login_password"]
|
||||||
user_dn, ok3 := session.Values["login_dn"]
|
user_dn, ok3 := session.Values["login_dn"]
|
||||||
|
|
||||||
|
var login_info *LoginInfo
|
||||||
if !(ok && ok2 && ok3) {
|
if !(ok && ok2 && ok3) {
|
||||||
return handleLogin(w, r)
|
login_info = handleLogin(w, r)
|
||||||
|
if login_info == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
login_info = &LoginInfo{
|
||||||
|
DN: user_dn.(string),
|
||||||
|
Username: username.(string),
|
||||||
|
Password: password.(string),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &LoginInfo{
|
l := ldapOpen(w)
|
||||||
DN: user_dn.(string),
|
if l == nil {
|
||||||
Username: username.(string),
|
return nil
|
||||||
Password: password.(string),
|
}
|
||||||
|
|
||||||
|
err = l.Bind(login_info.DN, login_info.Password)
|
||||||
|
if err != nil {
|
||||||
|
delete(session.Values, "login_username")
|
||||||
|
delete(session.Values, "login_password")
|
||||||
|
delete(session.Values, "login_dn")
|
||||||
|
|
||||||
|
err = session.Save(r, w)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return checkLogin(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
searchRequest := ldap.NewSearchRequest(
|
||||||
|
login_info.DN,
|
||||||
|
ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false,
|
||||||
|
fmt.Sprintf("(&(objectClass=organizationalPerson))"),
|
||||||
|
[]string{"dn", "displayname", "givenname", "sn", "mail"},
|
||||||
|
nil)
|
||||||
|
|
||||||
|
sr, err := l.Search(searchRequest)
|
||||||
|
if err!= nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sr.Entries) != 1 {
|
||||||
|
http.Error(w, fmt.Sprintf("Multiple entries: %#v", sr.Entries), http.StatusInternalServerError)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &LoginStatus{
|
||||||
|
Info: login_info,
|
||||||
|
conn: l,
|
||||||
|
UserEntry: sr.Entries[0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,3 +304,57 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProfileTplData struct {
|
||||||
|
Status *LoginStatus
|
||||||
|
ErrorMessage string
|
||||||
|
Success bool
|
||||||
|
Mail string
|
||||||
|
DisplayName string
|
||||||
|
GivenName string
|
||||||
|
Surname string
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleProfile(w http.ResponseWriter, r *http.Request) {
|
||||||
|
templateProfile := template.Must(template.ParseFiles("templates/layout.html", "templates/profile.html"))
|
||||||
|
|
||||||
|
login := checkLogin(w, r)
|
||||||
|
if login == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := &ProfileTplData{
|
||||||
|
Status: login,
|
||||||
|
ErrorMessage: "",
|
||||||
|
Success: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Method == "POST" {
|
||||||
|
r.ParseForm()
|
||||||
|
|
||||||
|
data.Mail = strings.Join(r.Form["mail"], "")
|
||||||
|
data.DisplayName = strings.Join(r.Form["display_name"], "")
|
||||||
|
data.GivenName = strings.Join(r.Form["given_name"], "")
|
||||||
|
data.Surname = strings.Join(r.Form["surname"], "")
|
||||||
|
|
||||||
|
modify_request := ldap.NewModifyRequest(login.Info.DN, nil)
|
||||||
|
modify_request.Replace("mail", []string{data.Mail})
|
||||||
|
modify_request.Replace("displayname", []string{data.DisplayName})
|
||||||
|
modify_request.Replace("givenname", []string{data.GivenName})
|
||||||
|
modify_request.Replace("sn", []string{data.Surname})
|
||||||
|
|
||||||
|
err := login.conn.Modify(modify_request)
|
||||||
|
if err != nil {
|
||||||
|
data.ErrorMessage = err.Error()
|
||||||
|
} else {
|
||||||
|
data.Success = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data.Mail = login.UserEntry.GetAttributeValue("mail")
|
||||||
|
data.DisplayName = login.UserEntry.GetAttributeValue("displayname")
|
||||||
|
data.GivenName = login.UserEntry.GetAttributeValue("givenname")
|
||||||
|
data.Surname = login.UserEntry.GetAttributeValue("sn")
|
||||||
|
}
|
||||||
|
|
||||||
|
templateProfile.Execute(w, data)
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,32 @@
|
||||||
{{define "title"}}Guichet{{end}}
|
{{define "title"}}{{end}}
|
||||||
|
|
||||||
{{define "body"}}
|
{{define "body"}}
|
||||||
<div class="alert alert-success">
|
<div class="alert alert-success">
|
||||||
Bienvenue, <strong>{{ .Username }}</strong> !
|
<div class="d-flex">
|
||||||
|
<span>Bienvenue, <strong>{{ .UserEntry.GetAttributeValue "givenname" }}</strong> !</span>
|
||||||
|
<a class="ml-auto btn btn-sm btn-dark" href="/logout">Se déconnecter</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
Gérer mon compte
|
Mon compte
|
||||||
</div>
|
</div>
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<a class="list-group-item list-group-item-action" href="/">Test</a>
|
<a class="list-group-item list-group-item-action" href="/profile">Modifier mon profil</a>
|
||||||
<a class="list-group-item list-group-item-action" href="/logout">Se déconnecter</a>
|
<a class="list-group-item list-group-item-action" href="/passwd">Modifier mon mot de passe</a>
|
||||||
|
<a class="list-group-item list-group-item-action" href="/invite">Inviter quelqu'un</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header">
|
||||||
|
Administration
|
||||||
|
</div>
|
||||||
|
<div class="list-group list-group-flush">
|
||||||
|
<a class="list-group-item list-group-item-action" href="/admin/users">Utilisateurs</a>
|
||||||
|
<a class="list-group-item list-group-item-action" href="/admin/groups">Groupes</a>
|
||||||
|
<a class="list-group-item list-group-item-action" href="/admin/ldap">Explorateur LDAP</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
45
templates/profile.html
Normal file
45
templates/profile.html
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{{define "title"}}Profile |{{end}}
|
||||||
|
|
||||||
|
{{define "body"}}
|
||||||
|
<h4>Modifier mon profil</h4>
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
{{if .ErrorMessage}}
|
||||||
|
<div class="alert alert-danger">Impossible de se connecter.
|
||||||
|
<div style="font-size: 0.8em">{{ .ErrorMessage }}</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{if .Success}}
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<div class="d-flex">
|
||||||
|
<span>Profil enregistré.</span>
|
||||||
|
<a class="ml-auto btn btn-sm btn-info" href="/">Retour</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Nom d'utilisateur:</label>
|
||||||
|
<input type="text" disabled="true" class="form-control" value="{{ .Status.Info.Username }}" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail">Adresse e-mail:</label>
|
||||||
|
<input type="text" id="mail" name="mail" class="form-control" value="{{ .Mail }}" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="display_name">Nom complet:</label>
|
||||||
|
<input type="text" id="display_name" name="display_name" class="form-control" value="{{ .DisplayName }}" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="given_name">Prénom:</label>
|
||||||
|
<input type="text" id="given_name" name="given_name" class="form-control" value="{{ .GivenName }}" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="surname">Nom de famille:</label>
|
||||||
|
<input type="text" id="surname" name="surname" class="form-control" value="{{ .Surname }}" />
|
||||||
|
</div>
|
||||||
|
<div class="d-flex">
|
||||||
|
<button type="submit" class="btn btn-primary">Enregistrer les modifications</button>
|
||||||
|
<a class="ml-auto btn btn-danger" href="/">Annuler</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
Loading…
Reference in a new issue