aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go122
-rw-r--r--templates/home.html25
-rw-r--r--templates/profile.html45
3 files changed, 181 insertions, 11 deletions
diff --git a/main.go b/main.go
index a58b2a1..aa2bad7 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,7 @@
package main
import (
+ "fmt"
"crypto/rand"
"crypto/tls"
"encoding/base64"
@@ -92,6 +93,7 @@ func main() {
http.HandleFunc("/", handleHome)
http.HandleFunc("/logout", handleLogout)
+ http.HandleFunc("/profile", handleProfile)
staticfiles := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", staticfiles))
@@ -108,6 +110,12 @@ type LoginInfo struct {
Password string
}
+type LoginStatus struct {
+ Info *LoginInfo
+ conn *ldap.Conn
+ UserEntry *ldap.Entry
+}
+
func logRequest(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
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)
if err != nil {
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"]
password, ok2 := session.Values["login_password"]
user_dn, ok3 := session.Values["login_dn"]
+
+ var login_info *LoginInfo
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{
- DN: user_dn.(string),
- Username: username.(string),
- Password: password.(string),
+ l := ldapOpen(w)
+ if l == nil {
+ return nil
+ }
+
+ 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
}
}
+
+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)
+}
diff --git a/templates/home.html b/templates/home.html
index 6a11af3..563e30a 100644
--- a/templates/home.html
+++ b/templates/home.html
@@ -1,17 +1,32 @@
-{{define "title"}}Guichet{{end}}
+{{define "title"}}{{end}}
{{define "body"}}
<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 class="card">
<div class="card-header">
- Gérer mon compte
+ Mon compte
+ </div>
+ <div class="list-group list-group-flush">
+ <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="/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="/">Test</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="/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>
diff --git a/templates/profile.html b/templates/profile.html
new file mode 100644
index 0000000..24556fa
--- /dev/null
+++ b/templates/profile.html
@@ -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}}