Fixed Change Password Bug

This commit is contained in:
Chris Mann 2023-07-25 21:35:22 +02:00
parent 9258cb52af
commit ccb628df39
23 changed files with 181 additions and 504 deletions

185
admin.go
View file

@ -17,15 +17,13 @@ func checkAdminLogin(w http.ResponseWriter, r *http.Request) *LoginStatus {
return nil
}
if !login.CanAdmin {
if !login.Common.CanAdmin {
http.Error(w, "Not authorized to perform administrative operations.", http.StatusUnauthorized)
return nil
}
return login
}
type EntryList []*ldap.Entry
func (d EntryList) Len() int {
return len(d)
}
@ -38,15 +36,6 @@ func (d EntryList) Less(i, j int) bool {
return d[i].DN < d[j].DN
}
type AdminUsersTplData struct {
Login *LoginStatus
UserNameAttr string
UserBaseDN string
Users EntryList
CanAdmin bool
LoggedIn bool
}
func handleAdminActivateUsers(w http.ResponseWriter, r *http.Request) {
templateAdminActivateUsers := getTemplate("admin_activate.html")
login := checkAdminLogin(w, r)
@ -72,12 +61,16 @@ func handleAdminActivateUsers(w http.ResponseWriter, r *http.Request) {
}
data := &AdminUsersTplData{
Login: login,
Login: NestedLoginTplData{
Login: login,
},
UserNameAttr: config.UserNameAttr,
UserBaseDN: config.UserBaseDN,
Users: EntryList(sr.Entries),
CanAdmin: login.CanAdmin,
LoggedIn: true,
Common: NestedCommonTplData{
CanAdmin: true,
LoggedIn: true,
},
}
templateAdminActivateUsers.Execute(w, data)
@ -133,12 +126,13 @@ func handleAdminUsers(w http.ResponseWriter, r *http.Request) {
}
data := &AdminUsersTplData{
Login: login,
Login: NestedLoginTplData{Login: login},
UserNameAttr: config.UserNameAttr,
UserBaseDN: config.UserBaseDN,
Users: EntryList(sr.Entries),
CanAdmin: login.CanAdmin,
LoggedIn: false,
Common: NestedCommonTplData{
CanAdmin: login.Common.CanAdmin,
LoggedIn: false},
}
sort.Sort(data.Users)
@ -154,15 +148,6 @@ func handleAdminUsers(w http.ResponseWriter, r *http.Request) {
templateAdminUsers.Execute(w, data)
}
type AdminGroupsTplData struct {
Login *LoginStatus
GroupNameAttr string
GroupBaseDN string
Groups EntryList
CanAdmin bool
LoggedIn bool
}
func handleAdminGroups(w http.ResponseWriter, r *http.Request) {
templateAdminGroups := getTemplate("admin_groups.html")
@ -185,27 +170,20 @@ func handleAdminGroups(w http.ResponseWriter, r *http.Request) {
}
data := &AdminGroupsTplData{
Login: login,
Login: NestedLoginTplData{
Login: login},
GroupNameAttr: config.GroupNameAttr,
GroupBaseDN: config.GroupBaseDN,
Groups: EntryList(sr.Entries),
CanAdmin: login.CanAdmin,
LoggedIn: false,
Common: NestedCommonTplData{
CanAdmin: login.Common.CanAdmin,
LoggedIn: false},
}
sort.Sort(data.Groups)
templateAdminGroups.Execute(w, data)
}
type AdminMailingTplData struct {
Login *LoginStatus
MailingNameAttr string
MailingBaseDN string
MailingLists EntryList
CanAdmin bool
LoggedIn bool
}
func handleAdminMailing(w http.ResponseWriter, r *http.Request) {
templateAdminMailing := getTemplate("admin_mailing.html")
@ -228,32 +206,20 @@ func handleAdminMailing(w http.ResponseWriter, r *http.Request) {
}
data := &AdminMailingTplData{
Login: login,
Login: NestedLoginTplData{
Login: login},
MailingNameAttr: config.MailingNameAttr,
MailingBaseDN: config.MailingBaseDN,
MailingLists: EntryList(sr.Entries),
CanAdmin: login.CanAdmin,
LoggedIn: false,
Common: NestedCommonTplData{
CanAdmin: login.Common.CanAdmin,
LoggedIn: false},
}
sort.Sort(data.MailingLists)
templateAdminMailing.Execute(w, data)
}
type AdminMailingListTplData struct {
Login *LoginStatus
MailingNameAttr string
MailingBaseDN string
MailingList *ldap.Entry
Members EntryList
PossibleNewMembers EntryList
AllowGuest bool
Error string
Success bool
CanAdmin bool
LoggedIn bool
}
func handleAdminMailingList(w http.ResponseWriter, r *http.Request) {
templateAdminMailingList := getTemplate("admin_mailing_list.html")
@ -424,7 +390,9 @@ func handleAdminMailingList(w http.ResponseWriter, r *http.Request) {
}
data := &AdminMailingListTplData{
Login: login,
Login: NestedLoginTplData{
Login: login,
},
MailingNameAttr: config.MailingNameAttr,
MailingBaseDN: config.MailingBaseDN,
@ -432,11 +400,11 @@ func handleAdminMailingList(w http.ResponseWriter, r *http.Request) {
Members: members,
PossibleNewMembers: possibleNewMembers,
AllowGuest: config.MailingGuestsBaseDN != "",
Error: dError,
Success: dSuccess,
CanAdmin: login.CanAdmin,
LoggedIn: true,
Common: NestedCommonTplData{
CanAdmin: true,
Error: dError,
Success: dSuccess,
LoggedIn: true},
}
sort.Sort(data.Members)
sort.Sort(data.PossibleNewMembers)
@ -448,54 +416,6 @@ func handleAdminMailingList(w http.ResponseWriter, r *http.Request) {
// LDAP EXPLORER
// ===================================================
type AdminLDAPTplData struct {
DN string
Path []PathItem
ChildrenOU []Child
ChildrenOther []Child
CanAddChild bool
Props map[string]*PropValues
CanDelete bool
HasMembers bool
Members []EntryName
PossibleNewMembers []EntryName
HasGroups bool
Groups []EntryName
PossibleNewGroups []EntryName
ListMemGro map[string]string
Error string
Success bool
CanAdmin bool
}
type EntryName struct {
DN string
Name string
}
type Child struct {
DN string
Identifier string
Name string
}
type PathItem struct {
DN string
Identifier string
Active bool
}
type PropValues struct {
Name string
Values []string
Editable bool
Deletable bool
}
func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
templateAdminLDAP := getTemplate("admin_ldap.html")
@ -922,32 +842,15 @@ func handleAdminLDAP(w http.ResponseWriter, r *http.Request) {
Groups: groups,
PossibleNewGroups: possibleNewGroups,
Error: dError,
Success: dSuccess,
CanAdmin: true,
Common: NestedCommonTplData{
CanAdmin: true,
LoggedIn: true,
Error: dError,
Success: dSuccess,
},
})
}
type CreateData struct {
SuperDN string
Path []PathItem
Template string
IdType string
IdValue string
DisplayName string
GivenName string
Member string
Mail string
Description string
StructuralObjectClass string
ObjectClass string
SN string
Error string
CanAdmin bool
}
func handleAdminCreate(w http.ResponseWriter, r *http.Request) {
templateAdminCreate := getTemplate("admin_create.html")
@ -1044,11 +947,11 @@ func handleAdminCreate(w http.ResponseWriter, r *http.Request) {
}
if len(object_class) == 0 {
data.Error = "No object class specified"
data.Common.Error = "No object class specified"
} else if match, err := regexp.MatchString("^[a-z]+$", data.IdType); err != nil || !match {
data.Error = "Invalid identifier type"
data.Common.Error = "Invalid identifier type"
} else if len(data.IdValue) == 0 {
data.Error = "No identifier specified"
data.Common.Error = "No identifier specified"
} else {
newUser := User{
DN: data.IdType + "=" + data.IdValue + "," + super_dn,
@ -1058,9 +961,9 @@ func handleAdminCreate(w http.ResponseWriter, r *http.Request) {
// req.Attribute("objectclass", object_class)
// req.Attribute("mail", []string{data.IdValue})
/*
if data.StructuralObjectClass != "" {
req.Attribute("structuralobjectclass", []string{data.StructuralObjectClass})
}
if data.StructuralObjectClass != "" {
req.Attribute("structuralobjectclass", []string{data.StructuralObjectClass})
}
*/
if data.Mail != "" {
newUser.Mail = data.Mail
@ -1102,7 +1005,7 @@ func handleAdminCreate(w http.ResponseWriter, r *http.Request) {
// // log.Printf(fmt.Sprintf("899: %v",req))
// // log.Printf(fmt.Sprintf("899: %v",data))
// if err != nil {
// data.Error = err.Error()
// data.Common.Error = err.Error()
// } else {
if template == "ml" {
http.Redirect(w, r, "/admin/mailing/"+data.IdValue, http.StatusFound)
@ -1112,7 +1015,7 @@ func handleAdminCreate(w http.ResponseWriter, r *http.Request) {
// }
}
}
data.CanAdmin = true
data.Common.CanAdmin = true
templateAdminCreate.Execute(w, data)
}

View file

@ -11,51 +11,6 @@ import (
"os"
)
type ConfigFile struct {
HttpBindAddr string `json:"http_bind_addr"`
LdapServerAddr string `json:"ldap_server_addr"`
LdapTLS bool `json:"ldap_tls"`
BaseDN string `json:"base_dn"`
UserBaseDN string `json:"user_base_dn"`
UserNameAttr string `json:"user_name_attr"`
GroupBaseDN string `json:"group_base_dn"`
GroupNameAttr string `json:"group_name_attr"`
MailingBaseDN string `json:"mailing_list_base_dn"`
MailingNameAttr string `json:"mailing_list_name_attr"`
MailingGuestsBaseDN string `json:"mailing_list_guest_user_base_dn"`
InvitationBaseDN string `json:"invitation_base_dn"`
InvitationNameAttr string `json:"invitation_name_attr"`
InvitedMailFormat string `json:"invited_mail_format"`
InvitedAutoGroups []string `json:"invited_auto_groups"`
WebAddress string `json:"web_address"`
MailFrom string `json:"mail_from"`
SMTPServer string `json:"smtp_server"`
SMTPUsername string `json:"smtp_username"`
SMTPPassword string `json:"smtp_password"`
AdminAccount string `json:"admin_account"`
GroupCanInvite string `json:"group_can_invite"`
GroupCanAdmin string `json:"group_can_admin"`
S3AdminEndpoint string `json:"s3_admin_endpoint"`
S3AdminToken string `json:"s3_admin_token"`
S3Endpoint string `json:"s3_endpoint"`
S3AccessKey string `json:"s3_access_key"`
S3SecretKey string `json:"s3_secret_key"`
S3Region string `json:"s3_region"`
S3Bucket string `json:"s3_bucket"`
Org string `json:"org"`
DomainName string `json:"domain_name"`
NewUserDN string `json:"new_user_dn"`
NewUserPassword string `json:"new_user_password"`
}
var configFlag = flag.String("config", "./config.json", "Configuration file path")
var config *ConfigFile

View file

@ -23,19 +23,6 @@ func handleDirectory(w http.ResponseWriter, r *http.Request) {
templateDirectory.Execute(w, nil)
}
type SearchResult struct {
DN string
Id string
DisplayName string
Email string
Description string
ProfilePicture string
}
type SearchResults struct {
Results []SearchResult
}
func handleDirectorySearch(w http.ResponseWriter, r *http.Request) {
templateDirectoryResults := template.Must(template.ParseFiles(templatePath + "/directory_results.html"))

22
home.go
View file

@ -6,14 +6,6 @@ package main
import "net/http"
type HomePageData struct {
Login *LoginStatus
BaseDN string
Org string
CanAdmin bool
LoggedIn bool
}
func handleHome(w http.ResponseWriter, r *http.Request) {
templateHome := getTemplate("home.html")
@ -28,15 +20,17 @@ func handleHome(w http.ResponseWriter, r *http.Request) {
can_admin := false
if login != nil {
can_admin = login.CanAdmin
can_admin = login.Common.CanAdmin
}
data := HomePageData{
Login: login,
BaseDN: config.BaseDN,
Org: config.Org,
CanAdmin: can_admin,
LoggedIn: true,
Login: NestedLoginTplData{
Login: login},
BaseDN: config.BaseDN,
Org: config.Org,
Common: NestedCommonTplData{
CanAdmin: can_admin,
LoggedIn: true},
}
templateHome.Execute(w, data)

122
invite.go
View file

@ -38,32 +38,12 @@ func checkInviterLogin(w http.ResponseWriter, r *http.Request) *LoginStatus {
// New account creation directly from interface
type PasswordFoundData struct {
ErrorMessage string
Success bool
Username string
Mail string
OtherMailbox string
CanAdmin bool
LoggedIn bool
}
type PasswordLostData struct {
ErrorMessage string
Success bool
Username string
Mail string
OtherMailbox string
CanAdmin bool
LoggedIn bool
}
func openNewUserLdap(config *ConfigFile) (*ldap.Conn, error) {
l, err := openLdap(config)
if err != nil {
log.Printf(fmt.Sprintf("openNewUserLdap 1 : %v %v", err, l))
log.Printf(fmt.Sprintf("openNewUserLdap 1 : %v", config))
// data.ErrorMessage = err.Error()
// data.Common.ErrorMessage = err.Error()
}
err = l.Bind(config.NewUserDN, config.NewUserPassword)
if err != nil {
@ -71,7 +51,7 @@ func openNewUserLdap(config *ConfigFile) (*ldap.Conn, error) {
log.Printf(fmt.Sprintf("openNewUserLdap 2 : %v", config.NewUserDN))
log.Printf(fmt.Sprintf("openNewUserLdap 2 : %v", config.NewUserPassword))
log.Printf(fmt.Sprintf("openNewUserLdap 2 : %v", config))
// data.ErrorMessage = err.Error()
// data.Common.ErrorMessage = err.Error()
}
return l, err
}
@ -83,8 +63,9 @@ func handleLostPassword(w http.ResponseWriter, r *http.Request) {
}
data := PasswordLostData{
CanAdmin: false,
LoggedIn: false,
Common: NestedCommonTplData{
CanAdmin: false,
LoggedIn: false},
}
if r.Method == "POST" {
@ -101,23 +82,23 @@ func handleLostPassword(w http.ResponseWriter, r *http.Request) {
ldapConn, err := openNewUserLdap(config)
if err != nil {
log.Printf(fmt.Sprintf("handleLostPassword 99 : %v %v", err, ldapConn))
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
}
err = passwordLost(user, config, ldapConn)
if err != nil {
log.Printf(fmt.Sprintf("handleLostPassword 104 : %v %v", err, ldapConn))
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
} else {
err = ldapConn.Bind(config.NewUserDN, config.NewUserPassword)
if err != nil {
log.Printf(fmt.Sprintf("handleLostPassword 109 : %v %v", err, ldapConn))
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
} else {
data.Success = true
data.Common.Success = true
}
}
}
data.CanAdmin = false
data.Common.CanAdmin = false
templateLostPasswordPage.Execute(w, data)
}
@ -205,26 +186,6 @@ func handleInvitationCode(w http.ResponseWriter, r *http.Request) {
// Common functions for new account
type NewAccountData struct {
Username string
DisplayName string
GivenName string
Surname string
Mail string
SuggestPW string
OtherEmail string
ErrorUsernameTaken bool
ErrorInvalidUsername bool
ErrorPasswordTooShort bool
ErrorPasswordMismatch bool
ErrorMessage string
WarningMessage string
Success bool
CanAdmin bool
LoggedIn bool
}
func handleNewAccount(w http.ResponseWriter, r *http.Request, l *ldap.Conn, invitedBy string) bool {
templateInviteNewAccount := getTemplate("invite_new_account.html")
@ -249,15 +210,15 @@ func handleNewAccount(w http.ResponseWriter, r *http.Request, l *ldap.Conn, invi
password2 := strings.Join(r.Form["password2"], "")
if password1 != password2 {
data.Success = false
data.Common.Success = false
data.ErrorPasswordMismatch = true
} else {
newUser.Password = password2
l.Bind(config.NewUserDN, config.NewUserPassword)
err := add(newUser, config, l)
if err != nil {
data.Success = false
data.ErrorMessage = err.Error()
data.Common.Success = false
data.Common.ErrorMessage = err.Error()
}
http.Redirect(w, r, "/admin/activate", http.StatusFound)
}
@ -267,11 +228,11 @@ func handleNewAccount(w http.ResponseWriter, r *http.Request, l *ldap.Conn, invi
} else {
data.SuggestPW = fmt.Sprintf("%s", suggestPassword())
}
data.CanAdmin = false
data.LoggedIn = false
data.Common.CanAdmin = false
data.Common.LoggedIn = false
templateInviteNewAccount.Execute(w, data)
return data.Success
return data.Common.Success
}
func tryCreateAccount(l *ldap.Conn, data *NewAccountData, pass1 string, pass2 string, invitedBy string) {
@ -294,7 +255,7 @@ func tryCreateAccount(l *ldap.Conn, data *NewAccountData, pass1 string, pass2 st
sr, err := l.Search(searchRq)
if err != nil {
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
checkFailed = true
}
@ -324,7 +285,7 @@ func tryCreateAccount(l *ldap.Conn, data *NewAccountData, pass1 string, pass2 st
req.Attribute("structuralobjectclass", []string{"inetOrgPerson"})
pw, err := SSHAEncode(pass1)
if err != nil {
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
return
}
req.Attribute("userpassword", []string{pw})
@ -345,7 +306,7 @@ func tryCreateAccount(l *ldap.Conn, data *NewAccountData, pass1 string, pass2 st
err = l.Add(req)
if err != nil {
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
return
}
@ -354,34 +315,15 @@ func tryCreateAccount(l *ldap.Conn, data *NewAccountData, pass1 string, pass2 st
req.Add("member", []string{userDn})
err = l.Modify(req)
if err != nil {
data.WarningMessage += fmt.Sprintf("Cannot add to %s: %s\n", group, err.Error())
data.Common.WarningMessage += fmt.Sprintf("Cannot add to %s: %s\n", group, err.Error())
}
}
data.Success = true
data.Common.Success = true
}
// ---- Code generation ----
type SendCodeData struct {
ErrorMessage string
ErrorInvalidEmail bool
Success bool
CodeDisplay string
CodeSentTo string
WebBaseAddress string
CanAdmin bool
}
type CodeMailFields struct {
From string
To string
Code string
InviteFrom string
WebBaseAddress string
CanAdmin bool
}
func handleInviteSendCode(w http.ResponseWriter, r *http.Request) {
templateInviteSendCode := getTemplate("invite_send_code.html")
@ -407,10 +349,10 @@ func handleInviteSendCode(w http.ResponseWriter, r *http.Request) {
// modify_request.Add("carLicense", []string{fmt.Sprintf("%s,%s,%s",code, code_id, code_pw)})
// err := login.conn.Modify(modify_request)
// if err != nil {
// data.ErrorMessage = err.Error()
// data.Common.ErrorMessage = err.Error()
// // return
// } else {
// data.Success = true
// data.Common.Success = true
// data.CodeDisplay = code
// }
log.Printf(fmt.Sprintf("279: %v %v %v", code, code_id, code_pw))
@ -423,13 +365,13 @@ func handleInviteSendCode(w http.ResponseWriter, r *http.Request) {
log.Printf(fmt.Sprintf("286: %v", addReq))
err := login.conn.Add(addReq)
if err != nil {
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
// return
} else {
data.Success = true
data.Common.Success = true
data.CodeDisplay = code
}
data.CanAdmin = login.CanAdmin
data.Common.CanAdmin = login.Common.CanAdmin
templateInviteSendCode.Execute(w, data)
@ -513,7 +455,7 @@ func trySendCode(login *LoginStatus, choice string, sendto string, data *SendCod
// // log.Printf(fmt.Sprintf("899: %v",req))
// // log.Printf(fmt.Sprintf("899: %v",data))
// if err != nil {
// data.Error = err.Error()
// data.Common.Error = err.Error()
// } else {
// if template == "ml" {
// http.Redirect(w, r, "/admin/mailing/"+data.IdValue, http.StatusFound)
@ -526,7 +468,7 @@ func trySendCode(login *LoginStatus, choice string, sendto string, data *SendCod
// req := ldap.NewAddRequest(inviteDn, nil)
// pw, err := SSHAEncode(code_pw)
// if err != nil {
// data.ErrorMessage = err.Error()
// data.Common.ErrorMessage = err.Error()
// return
// }
// req.Attribute("employeeNumber", []string{pw})
@ -535,13 +477,13 @@ func trySendCode(login *LoginStatus, choice string, sendto string, data *SendCod
// err = login.conn.Add(req)
// if err != nil {
// log.Printf(fmt.Sprintf("286: %v", req))
// data.ErrorMessage = err.Error()
// data.Common.ErrorMessage = err.Error()
// return
// }
// If we want to display it, do so
if choice == "display" {
data.Success = true
data.Common.Success = true
data.CodeDisplay = code
return
}
@ -569,12 +511,12 @@ func trySendCode(login *LoginStatus, choice string, sendto string, data *SendCod
// }
// err = smtp.SendMail(config.SMTPServer, auth, config.MailFrom, []string{sendto}, buf)
// if err != nil {
// data.ErrorMessage = err.Error()
// data.Common.ErrorMessage = err.Error()
// return
// }
// log.Printf("Mail sent.")
data.Success = true
data.Common.Success = true
data.CodeSentTo = sendto
}

View file

@ -13,20 +13,6 @@ import (
"github.com/go-ldap/ldap/v3"
)
type LoginInfo struct {
Username string
DN string
Password string
}
type LoginStatus struct {
Info *LoginInfo
conn *ldap.Conn
UserEntry *ldap.Entry
CanAdmin bool
CanInvite bool
}
func (login *LoginStatus) WelcomeName() string {
ret := login.UserEntry.GetAttributeValue("givenName")
if ret == "" {
@ -49,15 +35,6 @@ func handleLogout(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusFound)
}
type LoginFormData struct {
Username string
WrongUser bool
WrongPass bool
ErrorMessage string
LoggedIn bool
CanAdmin bool
}
func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
templateLogin := getTemplate("login.html")
@ -80,8 +57,11 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
if err != nil {
data := &LoginFormData{
Username: username,
LoggedIn: false,
CanAdmin: false,
Common: NestedCommonTplData{
CanAdmin: false,
CanInvite: true,
LoggedIn: false,
},
}
if ldap.IsErrorWithCode(err, ldap.LDAPResultInvalidCredentials) {
data.WrongPass = true
@ -91,7 +71,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
log.Printf("%v", err)
log.Printf("%v", user_dn)
log.Printf("%v", username)
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
}
templateLogin.Execute(w, data)
}
@ -99,7 +79,11 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
return loginInfo
} else if r.Method == "GET" {
templateLogin.Execute(w, LoginFormData{CanAdmin: false})
templateLogin.Execute(w, LoginFormData{
Common: NestedCommonTplData{
CanAdmin: false,
CanInvite: true,
LoggedIn: false}})
return nil
} else {
http.Error(w, "Unsupported method", http.StatusBadRequest)

58
main.go
View file

@ -12,35 +12,21 @@ import (
// "encoding/json"
"flag"
// "fmt"
"html/template"
// "io/ioutil"
"log"
"net/http"
// "os"
"strings"
// "strings"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
)
const SESSION_NAME = "guichet_session"
var staticPath = "./static"
var templatePath = "./templates"
var store sessions.Store = nil
func getTemplate(name string) *template.Template {
return template.Must(template.New("layout.html").Funcs(template.FuncMap{
"contains": strings.Contains,
}).ParseFiles(
templatePath+"/layout.html",
templatePath+"/"+name,
))
}
func main() {
flag.Parse()
config_file := readConfig()
@ -52,45 +38,7 @@ func main() {
log.Fatal(err)
}
store = sessions.NewCookieStore(session_key)
r := mux.NewRouter()
r.HandleFunc("/", handleHome)
r.HandleFunc("/logout", handleLogout)
r.HandleFunc("/profile", handleProfile)
r.HandleFunc("/passwd", handlePasswd)
r.HandleFunc("/picture/{name}", handleDownloadPicture)
r.HandleFunc("/admin/activate", handleAdminActivateUsers)
r.HandleFunc("/admin/unactivate/{cn}", handleAdminUnactivateUser)
r.HandleFunc("/admin/activate/{cn}", handleAdminActivateUser)
r.HandleFunc("/directory/search", handleDirectorySearch)
r.HandleFunc("/directory", handleDirectory)
r.HandleFunc("/garage/key", handleGarageKey)
r.HandleFunc("/garage/website", handleGarageWebsiteList)
r.HandleFunc("/garage/website/new", handleGarageWebsiteNew)
r.HandleFunc("/garage/website/b/{bucket}", handleGarageWebsiteInspect)
r.HandleFunc("/invite/new_account", handleInviteNewAccount)
r.HandleFunc("/invite/send_code", handleInviteSendCode)
r.HandleFunc("/gpassword/{code}", handleFoundPassword)
r.HandleFunc("/gpas", handleLostPassword)
r.HandleFunc("/invitation/{code}", handleInvitationCode)
r.HandleFunc("/admin/users", handleAdminUsers)
r.HandleFunc("/admin/groups", handleAdminGroups)
r.HandleFunc("/admin/mailing", handleAdminMailing)
r.HandleFunc("/admin/mailing/{id}", handleAdminMailingList)
r.HandleFunc("/admin/ldap/{dn}", handleAdminLDAP)
r.HandleFunc("/admin/create/{template}/{super_dn}", handleAdminCreate)
staticfiles := http.FileServer(http.Dir(staticPath))
r.Handle("/static/{file:.*}", http.StripPrefix("/static/", staticfiles))
// log.Printf("Starting HTTP server on %s", config.HttpBindAddr)
err = http.ListenAndServe(config.HttpBindAddr, logRequest(r))
_, err = makeGVRouter()
if err != nil {
log.Fatal("Cannot start http server: ", err)
}

View file

@ -11,26 +11,6 @@ import (
"github.com/go-ldap/ldap/v3"
)
/*
Represents a user
*/
type User struct {
DN string
CN string
GivenName string
DisplayName string
Mail string
SN string
UID string
Description string
Password string
OtherMailbox string
CanAdmin bool
CanInvite bool
UserEntry *ldap.Entry
SeeAlso string
}
func get(user User, config *ConfigFile, ldapConn *ldap.Conn) (*User, error) {
searchReq := ldap.NewSearchRequest(
user.DN,

View file

@ -10,33 +10,6 @@ import (
"github.com/gorilla/mux"
)
type ProfileTplData struct {
Status *LoginStatus
ErrorMessage string
Success bool
Mail string
DisplayName string
GivenName string
Surname string
Description string
Login *LoginStatus
CanAdmin bool
LoggedIn bool
}
//ProfilePicture string
//Visibility string
type PasswdTplData struct {
Status *LoginStatus
ErrorMessage string
TooShortError bool
NoMatchError bool
Success bool
CanAdmin bool
LoggedIn bool
}
func handleProfile(w http.ResponseWriter, r *http.Request) {
templateProfile := getTemplate("profile.html")
@ -44,19 +17,25 @@ func handleProfile(w http.ResponseWriter, r *http.Request) {
if login == nil {
templatePasswd := getTemplate("passwd.html")
templatePasswd.Execute(w, PasswdTplData{
LoggedIn: false,
CanAdmin: false,
Common: NestedCommonTplData{
CanAdmin: false,
LoggedIn: false},
})
return
}
data := &ProfileTplData{
Status: login,
Login: login,
ErrorMessage: "",
Success: false,
CanAdmin: login.CanAdmin,
LoggedIn: true,
Login: NestedLoginTplData{
Status: login,
Login: login,
},
Common: NestedCommonTplData{
CanAdmin: login.Common.CanAdmin,
LoggedIn: true,
ErrorMessage: "",
Success: false,
},
}
data.Mail = login.UserEntry.GetAttributeValue("mail")
@ -85,21 +64,21 @@ func handleProfile(w http.ResponseWriter, r *http.Request) {
if user.DisplayName != "" {
err := modify(user, config, login.conn)
if err != nil {
data.ErrorMessage = "handleProfile : " + err.Error()
data.Common.ErrorMessage = "handleProfile : " + err.Error()
} else {
data.Success = true
data.Common.Success = true
}
}
findUser, err := get(user, config, login.conn)
if err != nil {
data.ErrorMessage = "handleProfile : " + err.Error()
data.Common.ErrorMessage = "handleProfile : " + err.Error()
}
data.DisplayName = findUser.DisplayName
data.GivenName = findUser.GivenName
data.Surname = findUser.SN
data.Description = findUser.Description
data.Mail = findUser.Mail
data.LoggedIn = false
data.Common.LoggedIn = false
/*
visible := strings.TrimSpace(strings.Join(r.Form["visibility"], ""))
@ -113,7 +92,7 @@ func handleProfile(w http.ResponseWriter, r *http.Request) {
/*
profilePicture, err := uploadProfilePicture(w, r, login)
if err != nil {
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
}
if profilePicture != "" {
data.ProfilePicture = profilePicture
@ -131,9 +110,9 @@ func handleProfile(w http.ResponseWriter, r *http.Request) {
// log.Printf(fmt.Sprintf("Profile:079: %v",err))
// log.Printf(fmt.Sprintf("Profile:079: %v",data))
// if err != nil {
// data.ErrorMessage = err.Error()
// data.Common.ErrorMessage = err.Error()
// } else {
// data.Success = true
// data.Common.Success = true
// }
}
@ -144,8 +123,9 @@ func handleProfile(w http.ResponseWriter, r *http.Request) {
func handleFoundPassword(w http.ResponseWriter, r *http.Request) {
templateFoundPasswordPage := getTemplate("passwd.html")
data := PasswdTplData{
CanAdmin: false,
LoggedIn: false,
Common: NestedCommonTplData{
CanAdmin: false,
LoggedIn: false},
}
code := mux.Vars(r)["code"]
// code = strings.TrimSpace(strings.Join([]string{code}, ""))
@ -153,7 +133,7 @@ func handleFoundPassword(w http.ResponseWriter, r *http.Request) {
ldapConn, err := openNewUserLdap(config)
if err != nil {
log.Printf(fmt.Sprint("handleFoundPassword / openNewUserLdap / %v", err))
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
}
codeArray := strings.Split(string(newCode), ";")
user := User{
@ -165,7 +145,7 @@ func handleFoundPassword(w http.ResponseWriter, r *http.Request) {
if err != nil {
log.Printf("handleFoundPassword / passwordFound %v", err)
log.Printf("handleFoundPassword / passwordFound %v", err)
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
}
if r.Method == "POST" {
r.ParseForm()
@ -183,23 +163,25 @@ func handleFoundPassword(w http.ResponseWriter, r *http.Request) {
Password: password,
}, config, ldapConn)
if err != nil {
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
} else {
data.Success = true
data.Common.Success = true
}
}
}
data.CanAdmin = false
data.Common.CanAdmin = false
templateFoundPasswordPage.Execute(w, data)
}
func handlePasswd(w http.ResponseWriter, r *http.Request) {
templatePasswd := getTemplate("passwd.html")
data := &PasswdTplData{
ErrorMessage: "",
Success: false,
CanAdmin: false,
LoggedIn: false,
Common: NestedCommonTplData{
CanAdmin: false,
LoggedIn: false,
ErrorMessage: "",
Success: false,
},
}
login := checkLogin(w, r)
@ -207,7 +189,7 @@ func handlePasswd(w http.ResponseWriter, r *http.Request) {
templatePasswd.Execute(w, data)
return
}
data.Status = login
data.Login.Status = login
if r.Method == "POST" {
r.ParseForm()
@ -225,12 +207,12 @@ func handlePasswd(w http.ResponseWriter, r *http.Request) {
Password: password,
}, config, login.conn)
if err != nil {
data.ErrorMessage = err.Error()
data.Common.ErrorMessage = err.Error()
} else {
data.Success = true
data.Common.Success = true
}
}
}
data.CanAdmin = false
data.Common.CanAdmin = false
templatePasswd.Execute(w, data)
}

View file

@ -60,8 +60,10 @@ func checkLogin(w http.ResponseWriter, r *http.Request) *LoginStatus {
Info: login_info,
conn: l,
UserEntry: userEntry,
CanAdmin: ldapUser.CanAdmin,
CanInvite: ldapUser.CanInvite,
Common: NestedCommonTplData{
CanAdmin: ldapUser.CanAdmin,
CanInvite: ldapUser.CanInvite,
},
}
return loginStatus
} else {

View file

@ -20,9 +20,9 @@
</nav>
</div>
{{if .Error}}
{{if .Common.Error}}
<div class="alert alert-danger mt-4">Impossible de créer l'objet.
<div style="font-size: 0.8em">{{ .Error }}</div>
<div style="font-size: 0.8em">{{ .Common.Error }}</div>
</div>
{{end}}

View file

@ -59,10 +59,10 @@
<hr class="mt-4" />
{{end}}
{{if .Success}}
{{if .Common.Success}}
<div class="alert alert-success mt-2">Modification enregistrée.</div>
{{end}}
{{if .Error}}
{{if .Common.Error}}
<div class="alert alert-danger mt-2">
Impossible d'effectuer la modification.
<div style="font-size: 0.8em">{{.Error}}</div>

View file

@ -10,10 +10,10 @@
<a class="ml-auto btn btn-dark" href="/admin/mailing">Liste des ML</a>
</div>
{{if .Success}}
{{if .Common.Success}}
<div class="alert alert-success mt-2">Modification enregistrée.</div>
{{end}}
{{if .Error}}
{{if .Common.Error}}
<div class="alert alert-danger mt-2">
Impossible d'effectuer la modification.
<div style="font-size: 0.8em">{{.Error}}</div>

View file

@ -179,7 +179,7 @@ hugo deploy
<tbody>
<tr>
<th scope="row">Nom d'utilisateur-ice</th>
<td>{{ .Status.Info.Username }}</td>
<td>{{ .Login.Status.Info.Username }}</td>
</tr>
<tr>
<th scope="row">Mot de passe</th>
@ -210,7 +210,7 @@ hugo deploy
<div class="card-body">
<p>Un exemple avec SCP :</p>
<pre>
scp -oHostKeyAlgorithms=+ssh-rsa -P2222 -r ./public {{ .Status.Info.Username }}@bagage.resdigita.org:mon_bucket/
scp -oHostKeyAlgorithms=+ssh-rsa -P2222 -r ./public {{ .Login.Status.Info.Username }}@bagage.resdigita.org:mon_bucket/
</pre>
</div>
</div>

View file

@ -35,7 +35,7 @@
</tr>
<tr>
<th scope="row">Document d'erreur</th>
<td>{{ .ErrorDoc }}</td>
<td>{{ .Common.ErrorDoc }}</td>
</tr>
<tr>
<th scope="row">Nombre de fichiers</th>

View file

@ -5,7 +5,7 @@
{{define "body"}}
<div class="alert alert-info">
Bienvenue, <strong>{{ .Login.WelcomeName }}</strong> !
Bienvenue, <strong>{{ .Login.Login.WelcomeName }}</strong> !
</div>
<div class="mt-3">

View file

@ -7,18 +7,18 @@
<div class="d-flex">
<h2>Création d'un nouveau compte</h2>
</div>
{{if .ErrorMessage}}
{{if .Common.ErrorMessage}}
<div class="alert alert-danger mt-4">Impossible de créer le compte.
<div style="font-size: 0.8em">{{ .ErrorMessage }}</div>
<div style="font-size: 0.8em">{{ .Common.ErrorMessage }}</div>
</div>
{{end}}
{{if .WarningMessage}}
{{if .Common.WarningMessage}}
<div class="alert alert-danger mt-4">Des erreurs se sont produites, le compte pourrait ne pas être totalement
fonctionnel.
<div style="font-size: 0.8em">{{ .WarningMessage }}</div>
<div style="font-size: 0.8em">{{ .Common.WarningMessage }}</div>
</div>
{{end}}
{{if .Success}}
{{if .Common.Success}}
<div class="alert alert-success mt-4">
Le compe a été créé !
Rendez-vous <a href="/logout">sur la page d'accueil</a> pour vous connecter avec ce nouveau compte.
@ -46,20 +46,20 @@
</div>
<div class="form-group">
<label for="username">Identifiant :</label>
<input type="text" id="username" name="username" class="form-control" value="{{ .Username }}" />
<input type="text" id="username" name="username" class="form-control" value="{{ .Login.Login.Username }}" />
<small class="form-text text-muted">
Votre identifiant doit être en minuscule.
</small>
</div>
<div id="calc-uid"></div>
<div id="calc-cn"></div>
{{if .ErrorInvalidUsername}}
{{if .Common.ErrorInvalidUsername}}
<div class="alert alert-warning">
Nom d'utilisateur invalide. Ne peut contenir que les caractères suivants : chiffres, lettres minuscules, point,
tiret bas (_) et tiret du milieu (-).
</div>
{{end}}
{{if .ErrorUsernameTaken}}
{{if .Common.ErrorUsernameTaken}}
<div class="alert alert-warning">
Ce nom d'utilisateur est déjà pris.
</div>
@ -80,7 +80,7 @@
caractères spéciaux sans modération !
</small>
</div>
{{if .ErrorPasswordTooShort}}
{{if .Common.ErrorPasswordTooShort}}
<div class="alert alert-warning">
Le mot de passe choisi est trop court (minimum 8 caractères).
</div>
@ -89,7 +89,7 @@
<label for="password2">Répéter le mot de passe :</label>
<input type="password" id="password2" name="password2" class="form-control" />
</div>
{{if .ErrorPasswordMismatch}}
{{if .Common.ErrorPasswordMismatch}}
<div class="alert alert-warning">
Les deux mots de passe entrés ne correspondent pas.
</div>

View file

@ -8,12 +8,12 @@
<a class="ml-auto btn btn-info" href="/">Retour</a>
</div>
{{if .ErrorMessage}}
{{if .Common.ErrorMessage}}
<div class="alert alert-danger mt-4">Impossible de génerer ou d'envoyer le code.
<div style="font-size: 0.8em">{{ .ErrorMessage }}</div>
<div style="font-size: 0.8em">{{ .Common.ErrorMessage }}</div>
</div>
{{end}}
{{if .Success}}
{{if .Common.Success}}
<div class="alert alert-success mt-4">
{{if .CodeSentTo}}
Un code d'invitation a bien été envoyé à <code>{{ .CodeSentTo }}</code>.
@ -41,7 +41,7 @@
</label>
<input class="form-control" type="text" name="sendto" id="sendto" placeholder="Addresse mail..." onclick="document.getElementById('choice_send').checked = true;" />
</div>
{{if .ErrorInvalidEmail}}
{{if .Common.ErrorInvalidEmail}}
<div class="alert alert-warning mt-4">
Addresse mail invalide.
</div>

View file

@ -55,7 +55,7 @@
<li><a href="https://www.lesgrandsvoisins.com/admin">Editer le site web</a></li>
<li><a href="https://www.lesgrandsvoisins.com/admin">Editer le blog</a></li>
</ul></li>
{{if .CanAdmin}}
{{if .Common.CanAdmin}}
<li>&lt;&nbsp;<a href="#">Administration</a>
<ul class="submenu">
<!-- <li><a href="/admin/activate">Administrer LDAP</a> -->
@ -67,7 +67,7 @@
{{end}}
<li>&lt;&nbsp;<a href="#">Compte</a>
<ul class="submenu">
{{if .LoggedIn}}
{{if .Common.LoggedIn}}
<li><a href="/logout">Se déconnecter</a></li>
<li><a href="/">Tableau de bord</a></li>
<li><a href="/profile">Modifier mon profil</a></li>

View file

@ -17,14 +17,14 @@
{{if .WrongPass}}
<div class="alert alert-danger">Mot de passe invalide.</div>
{{end}}
{{if .ErrorMessage}}
{{if .Common.ErrorMessage}}
<div class="alert alert-danger">Impossible de se connecter.
<div style="font-size: 0.8em">{{ .ErrorMessage }}</div>
<div style="font-size: 0.8em">{{ .Common.ErrorMessage }}</div>
</div>
{{end}}
<div class="form-group">
<label for="username">Identifiant :</label>
<input type="text" name="username" id="username" class="form-control" value="{{ .Username }}" />
<input type="text" name="username" id="username" class="form-control" value="{{ .Login.Login.Username }}" />
</div>
<div class="form-group">
<label for="password">Mot de passe :</label>

View file

@ -8,12 +8,12 @@
<h2>Modifier mon mot de passe</h2>
</div>
{{if .ErrorMessage}}
{{if .Common.ErrorMessage}}
<div class="alert alert-danger mt-4">Impossible d'effectuer la modification.
<div style="font-size: 0.8em">{{ .ErrorMessage }}</div>
<div style="font-size: 0.8em">{{ .Common.ErrorMessage }}</div>
</div>
{{end}}
{{if .Success}}
{{if .Common.Success}}
<div class="alert alert-success mt-4">
Nouveau mot de passe enregistré.
</div>

View file

@ -8,12 +8,12 @@
<p>Refaire son mot de passe</p>
{{if .ErrorMessage}}
{{if .Common.ErrorMessage}}
<div class="alert alert-danger">Impossible
<div style="font-size: 0.8em">{{ .ErrorMessage }}</div>
<div style="font-size: 0.8em">{{ .Common.ErrorMessage }}</div>
</div>
{{end}}
{{if .Success}}
{{if .Common.Success}}
<div class="alert alert-success mt-4">
Email envoyé au courriel de secours.
</div>
@ -24,7 +24,7 @@
<form method="POST">
<div class="form-group">
<label for="username">Ou identifiant :</label>
<input type="text" name="username" id="username" class="form-control" value="{{ .Username }}" />
<input type="text" name="username" id="username" class="form-control" value="{{ .Login.Login.Username }}" />
</div>
<div class="form-group">
<label for="mail">ou mail (interne aux GV) :</label>

View file

@ -8,12 +8,12 @@
<h2>Modifier mon profil</h2>
</div>
{{if .ErrorMessage}}
{{if .Common.ErrorMessage}}
<div class="alert alert-danger mt-4">Impossible d'effectuer la modification.
<div style="font-size: 0.8em">{{ .ErrorMessage }}</div>
<div style="font-size: 0.8em">{{ .Common.ErrorMessage }}</div>
</div>
{{end}}
{{if .Success}}
{{if .Common.Success}}
<div class="alert alert-success mt-4">
Profil enregistré.
</div>
@ -22,7 +22,7 @@
<div class="form-row">
<div class="form-group col-md-6">
<label>Identifiant:</label>
<input type="text" disabled="true" class="form-control" value="{{ .Status.Info.Username }}" />
<input type="text" disabled="true" class="form-control" value="{{ .Login.Status.Info.Username }}" />
</div>
<div class="form-group col-md-6">
<label for="mail">Adresse e-mail:</label>