guichet/login.go

150 lines
3.3 KiB
Go
Raw Normal View History

/*
login handles login and current-user verification
*/
package main
import (
"fmt"
"log"
"net/http"
"strings"
"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 == "" {
ret = login.UserEntry.GetAttributeValue("displayName")
}
if ret == "" {
ret = login.Info.Username
}
return ret
}
func handleLogout(w http.ResponseWriter, r *http.Request) {
2023-07-25 12:13:14 +00:00
err := logout(w, r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/", http.StatusFound)
}
type LoginFormData struct {
Username string
WrongUser bool
WrongPass bool
ErrorMessage string
2023-07-24 14:28:22 +00:00
LoggedIn bool
CanAdmin bool
}
func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
templateLogin := getTemplate("login.html")
2023-07-25 12:13:14 +00:00
loginStatus := checkLogin(w, r)
if loginStatus != nil {
handleHome(w, r)
return loginStatus.Info
}
if r.Method == "GET" {
templateLogin.Execute(w, LoginFormData{CanAdmin: false})
return nil
} else if r.Method == "POST" {
// log.Printf("%v", "Parsing Form handleLogin")
r.ParseForm()
username := strings.Join(r.Form["username"], "")
password := strings.Join(r.Form["password"], "")
user_dn := fmt.Sprintf("%s=%s,%s", config.UserNameAttr, username, config.UserBaseDN)
2023-07-21 08:16:51 +00:00
// log.Printf("%v", user_dn)
// log.Printf("%v", username)
if strings.EqualFold(username, config.AdminAccount) {
user_dn = username
}
2023-07-21 11:52:05 +00:00
loginInfo, err := doLogin(w, r, username, user_dn, password)
// log.Printf("%v", loginInfo)
2023-07-21 08:30:17 +00:00
if err != nil {
data := &LoginFormData{
Username: username,
2023-07-24 14:28:22 +00:00
LoggedIn: false,
CanAdmin: false,
2023-07-21 08:30:17 +00:00
}
if ldap.IsErrorWithCode(err, ldap.LDAPResultInvalidCredentials) {
data.WrongPass = true
} else if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
data.WrongUser = true
} else {
log.Printf("%v", err)
log.Printf("%v", user_dn)
log.Printf("%v", username)
2023-07-21 08:30:17 +00:00
data.ErrorMessage = err.Error()
}
templateLogin.Execute(w, data)
}
2023-07-21 08:26:35 +00:00
return loginInfo
2023-07-21 08:22:23 +00:00
2023-07-21 08:16:51 +00:00
} else {
http.Error(w, "Unsupported method", http.StatusBadRequest)
return nil
}
}
2023-07-21 11:50:34 +00:00
func doLogin(w http.ResponseWriter, r *http.Request, username string, user_dn string, password string) (*LoginInfo, error) {
2023-07-21 12:15:44 +00:00
l, _ := ldapOpen(w)
2023-07-21 08:16:51 +00:00
err := l.Bind(user_dn, password)
2023-07-21 08:30:17 +00:00
if err != nil {
log.Printf("doLogin : %v", err)
log.Printf("doLogin : %v", user_dn)
2023-07-21 11:50:34 +00:00
return nil, err
2023-07-21 08:16:51 +00:00
}
2023-07-21 08:16:51 +00:00
// Successfully logged in, save it to session
session, err := store.Get(r, SESSION_NAME)
if err != nil {
session, _ = store.New(r, SESSION_NAME)
}
2023-07-21 08:16:51 +00:00
session.Values["login_username"] = username
session.Values["login_password"] = password
session.Values["login_dn"] = user_dn
2023-07-21 08:16:51 +00:00
err = session.Save(r, w)
if err != nil {
log.Printf("doLogin Session Save: %v", err)
2023-07-21 08:16:51 +00:00
http.Error(w, err.Error(), http.StatusInternalServerError)
2023-07-21 11:50:34 +00:00
return nil, err
}
2023-07-21 08:16:51 +00:00
2023-07-21 08:30:17 +00:00
LoginInfo := LoginInfo{
2023-07-21 08:16:51 +00:00
DN: user_dn,
Username: username,
Password: password,
}
2023-07-21 11:50:34 +00:00
return &LoginInfo, nil
}