Refactoring

This commit is contained in:
Chris Mann 2023-07-26 09:00:42 +02:00
parent b536e30ce1
commit f87aa1a63f
4 changed files with 119 additions and 277 deletions

View file

@ -1,5 +1,5 @@
BIN=guichet BIN=guichet
SRC=main.go model.go view.go controller.go utils.go model-user.go view-admin.go view-home.go view-invite.go view-login.go view-passwd.go view-user.go utils-http.go utils-ldap.go utils-config.go directory.go garage.go picture.go session.go utils-ssha.go SRC=main.go model.go view.go controller.go utils.go model-user.go model-passwd.go view-admin.go view-home.go view-invite.go view-login.go view-passwd.go view-user.go utils-http.go utils-ldap.go utils-config.go directory.go garage.go picture.go session.go utils-ssha.go
# ssha.go profile.go admin.go invite.go directory.go utils.go picture.go login.go config.go http-utils.go home.go model-user.go gpas.go session.go model.go view.go controller.go utils-ldap.go # ssha.go profile.go admin.go invite.go directory.go utils.go picture.go login.go config.go http-utils.go home.go model-user.go gpas.go session.go model.go view.go controller.go utils-ldap.go

View file

@ -65,7 +65,7 @@ func makeGVRouter() (*mux.Router, error) {
r.HandleFunc("/session/logout", handleLogout) r.HandleFunc("/session/logout", handleLogout)
r.HandleFunc("/user", handleProfile) r.HandleFunc("/user", handleUser)
r.HandleFunc("/user/new", handleInviteNewAccount) r.HandleFunc("/user/new", handleInviteNewAccount)
r.HandleFunc("/picture/{name}", handleDownloadPicture) r.HandleFunc("/picture/{name}", handleDownloadPicture)

View file

@ -1,169 +1,110 @@
/* package main
gpas is GVoisin password reset
*/ import (
b64 "encoding/base64"
package main "fmt"
"log"
import ( "net/http"
"bytes" "strings"
"errors"
"fmt" "github.com/gorilla/mux"
"html/template" )
"log"
func handleFoundPassword(w http.ResponseWriter, r *http.Request) {
// "github.com/emersion/go-sasl" templateFoundPasswordPage := getTemplate("passwd.html")
// "github.com/emersion/go-smtp" data := PasswdTplData{
"net/smtp" Common: NestedCommonTplData{
CanAdmin: false,
"github.com/go-ldap/ldap/v3" LoggedIn: false},
// "strings" }
b64 "encoding/base64" code := mux.Vars(r)["code"]
) // code = strings.TrimSpace(strings.Join([]string{code}, ""))
newCode, _ := b64.URLEncoding.DecodeString(code)
// type InvitationAccount struct { ldapConn, err := openNewUserLdap(config)
// UID string if err != nil {
// Password string log.Printf(fmt.Sprint("handleFoundPassword / openNewUserLdap / %v", err))
// BaseDN string data.Common.ErrorMessage = err.Error()
// } }
codeArray := strings.Split(string(newCode), ";")
// var EMAIL_REGEXP := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") user := User{
UID: codeArray[0],
func passwordLost(user User, config *ConfigFile, ldapConn *ldap.Conn) error { Password: codeArray[1],
if user.CN == "" && user.Mail == "" && user.OtherMailbox == "" { DN: "uid=" + codeArray[0] + ",ou=invitations,dc=resdigita,dc=org",
return errors.New("Il n'y a pas de quoi identifier l'utilisateur") }
} user.SeeAlso, err = passwordFound(user, config, ldapConn)
searchFilter := "(|" if err != nil {
if user.CN != "" { log.Printf("handleFoundPassword / passwordFound %v", err)
searchFilter += "(cn=" + user.UID + ")" log.Printf("handleFoundPassword / passwordFound %v", err)
} data.Common.ErrorMessage = err.Error()
if user.Mail != "" { }
searchFilter += "(mail=" + user.Mail + ")" if r.Method == "POST" {
} r.ParseForm()
if user.OtherMailbox != "" {
searchFilter += "(carLicense=" + user.OtherMailbox + ")" password := strings.Join(r.Form["password"], "")
} password2 := strings.Join(r.Form["password2"], "")
searchFilter += ")"
searchReq := ldap.NewSearchRequest(config.UserBaseDN, ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false, searchFilter, []string{"cn", "uid", "mail", "carLicense", "sn", "displayName", "givenName"}, nil) if len(password) < 8 {
searchRes, err := ldapConn.Search(searchReq) data.TooShortError = true
if err != nil { } else if password2 != password {
log.Printf(fmt.Sprintf("passwordLost 49 : %v %v", err, ldapConn)) data.NoMatchError = true
log.Printf(fmt.Sprintf("passwordLost 50 : %v", searchReq)) } else {
log.Printf(fmt.Sprintf("passwordLost 51: %v", user)) err := passwd(User{
return err DN: user.SeeAlso,
} Password: password,
if len(searchRes.Entries) == 0 { }, config, ldapConn)
log.Printf("Il n'y a pas d'utilisateur qui correspond %v", searchReq) if err != nil {
return errors.New("Il n'y a pas d'utilisateur qui correspond") data.Common.ErrorMessage = err.Error()
} } else {
// log.Printf(fmt.Sprintf("passwordLost 58 : %v", user)) data.Common.Success = true
// log.Printf(fmt.Sprintf("passwordLost 59 : %v", searchRes.Entries[0])) }
// log.Printf(fmt.Sprintf("passwordLost 60 : %v", searchRes.Entries[0].GetAttributeValue("cn"))) }
// log.Printf(fmt.Sprintf("passwordLost 61 : %v", searchRes.Entries[0].GetAttributeValue("uid"))) }
// log.Printf(fmt.Sprintf("passwordLost 62 : %v", searchRes.Entries[0].GetAttributeValue("mail"))) data.Common.CanAdmin = false
// log.Printf(fmt.Sprintf("passwordLost 63 : %v", searchRes.Entries[0].GetAttributeValue("carLicense"))) templateFoundPasswordPage.Execute(w, data)
// Préparation du courriel à envoyer }
user.Password = suggestPassword()
code := b64.URLEncoding.EncodeToString([]byte(user.UID + ";" + user.Password)) func handlePasswd(w http.ResponseWriter, r *http.Request) {
user.DN = "uid=" + searchRes.Entries[0].GetAttributeValue("cn") + ",ou=invitations,dc=resdigita,dc=org" templatePasswd := getTemplate("passwd.html")
user.UID = searchRes.Entries[0].GetAttributeValue("cn") data := &PasswdTplData{
user.CN = searchRes.Entries[0].GetAttributeValue("cn") Common: NestedCommonTplData{
user.Mail = searchRes.Entries[0].GetAttributeValue("mail") CanAdmin: false,
user.OtherMailbox = searchRes.Entries[0].GetAttributeValue("carLicense") LoggedIn: true,
/* Check for outstanding invitation */ ErrorMessage: "",
searchReq = ldap.NewSearchRequest(config.InvitationBaseDN, ldap.ScopeBaseObject, Success: false,
ldap.NeverDerefAliases, 0, 0, false, "(uid="+user.UID+")", []string{"seeAlso"}, nil) },
searchRes, err = ldapConn.Search(searchReq) }
if err != nil {
log.Printf(fmt.Sprintf("passwordLost (Check existing invitation) : %v", err)) login := checkLogin(w, r)
log.Printf(fmt.Sprintf("passwordLost (Check existing invitation) : %v", user)) if login == nil {
return err data.Common.LoggedIn = false
} templatePasswd.Execute(w, data)
if len(searchRes.Entries) == 0 { return
/* Add the invitation */ }
addReq := ldap.NewAddRequest( data.Login.Status = login
user.DN, data.Common.CanAdmin = login.Common.CanAdmin
nil)
addReq.Attribute("objectClass", []string{"top", "account", "simpleSecurityObject"}) if r.Method == "POST" {
addReq.Attribute("uid", []string{user.UID}) r.ParseForm()
addReq.Attribute("userPassword", []string{"absdefghi"})
addReq.Attribute("seeAlso", []string{config.UserNameAttr + "=" + user.UID + "," + config.UserBaseDN}) password := strings.Join(r.Form["password"], "")
err = ldapConn.Add(addReq) password2 := strings.Join(r.Form["password2"], "")
if err != nil {
log.Printf(fmt.Sprintf("passwordLost 83 : %v", err)) if len(password) < 8 {
log.Printf(fmt.Sprintf("passwordLost 84 : %v", user)) data.TooShortError = true
// log.Printf(fmt.Sprintf("passwordLost 85 : %v", searchRes.Entries[0])) } else if password2 != password {
// For some reason I get here even if the entry exists already data.NoMatchError = true
return err } else {
} err := passwd(User{
} DN: login.Info.DN,
err = passwd(user, config, ldapConn) Password: password,
if err != nil { }, config, login.conn)
log.Printf(fmt.Sprintf("passwordLost 90 : %v", err)) if err != nil {
log.Printf(fmt.Sprintf("passwordLost 91 : %v", user)) data.Common.ErrorMessage = err.Error()
log.Printf(fmt.Sprintf("passwordLost 92 : %v", searchRes.Entries[0])) } else {
return err data.Common.Success = true
} }
templateMail := template.Must(template.ParseFiles(templatePath + "/lost_password_email.txt")) }
buf := bytes.NewBuffer([]byte{}) }
templateMail.Execute(buf, &CodeMailFields{ data.Common.CanAdmin = false
To: user.OtherMailbox, templatePasswd.Execute(w, data)
From: config.MailFrom, }
InviteFrom: user.UID,
Code: code,
WebBaseAddress: config.WebAddress,
})
// message := []byte("Hi " + user.OtherMailbox)
log.Printf("Sending mail to: %s", user.OtherMailbox)
// var auth sasl.Client = nil
// if config.SMTPUsername != "" {
// auth = sasl.NewPlainClient("", config.SMTPUsername, config.SMTPPassword)
// }
message := buf.Bytes()
auth := smtp.PlainAuth("", config.SMTPUsername, config.SMTPPassword, config.SMTPServer)
log.Printf("auth: %v", auth)
err = smtp.SendMail(config.SMTPServer+":587", auth, config.SMTPUsername, []string{user.OtherMailbox}, message)
if err != nil {
log.Printf("email send error %v", err)
return err
}
log.Printf("Mail sent.")
return nil
}
func passwordFound(user User, config *ConfigFile, ldapConn *ldap.Conn) (string, error) {
l, err := openLdap(config)
if err != nil {
log.Printf("passwordFound %v", err)
log.Printf("passwordFound Config : %v", config)
return "", err
}
if user.DN == "" && user.UID != "" {
user.DN = "uid=" + user.UID + ",ou=invitations,dc=resdigita,dc=org"
}
err = l.Bind(user.DN, user.Password)
if err != nil {
log.Printf("passwordFound %v", err)
log.Printf("passwordFound %v", user.DN)
log.Printf("passwordFound %v", user.UID)
return "", err
}
searchReq := ldap.NewSearchRequest(user.DN, ldap.ScopeBaseObject,
ldap.NeverDerefAliases, 0, 0, false, "(uid="+user.UID+")", []string{"seeAlso"}, nil)
var searchRes *ldap.SearchResult
searchRes, err = ldapConn.Search(searchReq)
if err != nil {
log.Printf("passwordFound %v", err)
log.Printf("passwordFound %v", searchReq)
log.Printf("passwordFound %v", ldapConn)
log.Printf("passwordFound %v", searchRes)
return "", err
}
if len(searchRes.Entries) == 0 {
log.Printf("passwordFound %v", err)
log.Printf("passwordFound %v", searchReq)
log.Printf("passwordFound %v", ldapConn)
log.Printf("passwordFound %v", searchRes)
return "", err
}
return searchRes.Entries[0].GetAttributeValue("seeAlso"), err
}

View file

@ -1,16 +1,15 @@
package main package main
import ( import (
b64 "encoding/base64" // b64 "encoding/base64"
"fmt" // "fmt"
"log" // "log"
"net/http" "net/http"
"strings" "strings"
// "github.com/gorilla/mux"
"github.com/gorilla/mux"
) )
func handleProfile(w http.ResponseWriter, r *http.Request) { func handleUser(w http.ResponseWriter, r *http.Request) {
templateProfile := getTemplate("user.html") templateProfile := getTemplate("user.html")
login := checkLogin(w, r) login := checkLogin(w, r)
@ -65,14 +64,14 @@ func handleProfile(w http.ResponseWriter, r *http.Request) {
if user.DisplayName != "" { if user.DisplayName != "" {
err := modify(user, config, login.conn) err := modify(user, config, login.conn)
if err != nil { if err != nil {
data.Common.ErrorMessage = "handleProfile : " + err.Error() data.Common.ErrorMessage = "handleUser : " + err.Error()
} else { } else {
data.Common.Success = true data.Common.Success = true
} }
} }
findUser, err := get(user, config, login.conn) findUser, err := get(user, config, login.conn)
if err != nil { if err != nil {
data.Common.ErrorMessage = "handleProfile : " + err.Error() data.Common.ErrorMessage = "handleUser : " + err.Error()
} }
data.DisplayName = findUser.DisplayName data.DisplayName = findUser.DisplayName
data.GivenName = findUser.GivenName data.GivenName = findUser.GivenName
@ -120,101 +119,3 @@ func handleProfile(w http.ResponseWriter, r *http.Request) {
templateProfile.Execute(w, data) templateProfile.Execute(w, data)
} }
func handleFoundPassword(w http.ResponseWriter, r *http.Request) {
templateFoundPasswordPage := getTemplate("passwd.html")
data := PasswdTplData{
Common: NestedCommonTplData{
CanAdmin: false,
LoggedIn: false},
}
code := mux.Vars(r)["code"]
// code = strings.TrimSpace(strings.Join([]string{code}, ""))
newCode, _ := b64.URLEncoding.DecodeString(code)
ldapConn, err := openNewUserLdap(config)
if err != nil {
log.Printf(fmt.Sprint("handleFoundPassword / openNewUserLdap / %v", err))
data.Common.ErrorMessage = err.Error()
}
codeArray := strings.Split(string(newCode), ";")
user := User{
UID: codeArray[0],
Password: codeArray[1],
DN: "uid=" + codeArray[0] + ",ou=invitations,dc=resdigita,dc=org",
}
user.SeeAlso, err = passwordFound(user, config, ldapConn)
if err != nil {
log.Printf("handleFoundPassword / passwordFound %v", err)
log.Printf("handleFoundPassword / passwordFound %v", err)
data.Common.ErrorMessage = err.Error()
}
if r.Method == "POST" {
r.ParseForm()
password := strings.Join(r.Form["password"], "")
password2 := strings.Join(r.Form["password2"], "")
if len(password) < 8 {
data.TooShortError = true
} else if password2 != password {
data.NoMatchError = true
} else {
err := passwd(User{
DN: user.SeeAlso,
Password: password,
}, config, ldapConn)
if err != nil {
data.Common.ErrorMessage = err.Error()
} else {
data.Common.Success = true
}
}
}
data.Common.CanAdmin = false
templateFoundPasswordPage.Execute(w, data)
}
func handlePasswd(w http.ResponseWriter, r *http.Request) {
templatePasswd := getTemplate("passwd.html")
data := &PasswdTplData{
Common: NestedCommonTplData{
CanAdmin: false,
LoggedIn: true,
ErrorMessage: "",
Success: false,
},
}
login := checkLogin(w, r)
if login == nil {
templatePasswd.Execute(w, data)
return
}
data.Login.Status = login
data.Common.CanAdmin = login.Common.CanAdmin
if r.Method == "POST" {
r.ParseForm()
password := strings.Join(r.Form["password"], "")
password2 := strings.Join(r.Form["password2"], "")
if len(password) < 8 {
data.TooShortError = true
} else if password2 != password {
data.NoMatchError = true
} else {
err := passwd(User{
DN: login.Info.DN,
Password: password,
}, config, login.conn)
if err != nil {
data.Common.ErrorMessage = err.Error()
} else {
data.Common.Success = true
}
}
}
data.Common.CanAdmin = false
templatePasswd.Execute(w, data)
}