aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go198
1 files changed, 21 insertions, 177 deletions
diff --git a/main.go b/main.go
index c809d25..ee1863c 100644
--- a/main.go
+++ b/main.go
@@ -2,10 +2,8 @@ package main
import (
"crypto/rand"
- "crypto/tls"
"encoding/json"
"flag"
- "fmt"
"html/template"
"io/ioutil"
"log"
@@ -146,6 +144,7 @@ func server(args []string) {
r := mux.NewRouter()
r.HandleFunc("/", handleHome)
+ r.HandleFunc("/login", handleLogin)
r.HandleFunc("/logout", handleLogout)
r.HandleFunc("/api/unstable/garage/bucket/{bucket}", handleAPIGarageBucket)
@@ -183,31 +182,6 @@ func server(args []string) {
}
}
-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 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)
@@ -215,149 +189,32 @@ func logRequest(handler http.Handler) http.Handler {
})
}
-func checkLogin(w http.ResponseWriter, r *http.Request) *LoginStatus {
- var login_info *LoginInfo
-
- session, err := store.Get(r, SESSION_NAME)
- if err == nil {
- username, ok := session.Values["login_username"]
- password, ok2 := session.Values["login_password"]
- user_dn, ok3 := session.Values["login_dn"]
-
- if ok && ok2 && ok3 {
- login_info = &LoginInfo{
- DN: user_dn.(string),
- Username: username.(string),
- Password: password.(string),
- }
- }
- }
-
- if login_info == nil {
- login_info = handleLogin(w, r)
- if login_info == nil {
- return nil
- }
- }
-
- 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)
- }
-
- loginStatus := &LoginStatus{
- Info: login_info,
- conn: l,
- }
-
- requestKind := "(objectClass=organizationalPerson)"
- if strings.EqualFold(login_info.DN, config.AdminAccount) {
- requestKind = "(objectclass=*)"
- }
- searchRequest := ldap.NewSearchRequest(
- login_info.DN,
- ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false,
- requestKind,
- []string{
- "dn",
- "displayname",
- "givenname",
- "sn",
- "mail",
- "memberof",
- "description",
- "garage_s3_access_key",
- FIELD_NAME_DIRECTORY_VISIBILITY,
- FIELD_NAME_PROFILE_PICTURE,
- },
- 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("Unable to find entry for %s", login_info.DN), http.StatusInternalServerError)
- return nil
- }
-
- loginStatus.UserEntry = sr.Entries[0]
-
- loginStatus.CanAdmin = strings.EqualFold(loginStatus.Info.DN, config.AdminAccount)
- loginStatus.CanInvite = false
- for _, attr := range loginStatus.UserEntry.Attributes {
- if strings.EqualFold(attr.Name, "memberof") {
- for _, group := range attr.Values {
- if config.GroupCanInvite != "" && strings.EqualFold(group, config.GroupCanInvite) {
- loginStatus.CanInvite = true
- }
- if config.GroupCanAdmin != "" && strings.EqualFold(group, config.GroupCanAdmin) {
- loginStatus.CanAdmin = true
- }
- }
- }
- }
-
- return loginStatus
-}
-
-func ldapOpen(w http.ResponseWriter) *ldap.Conn {
- l, err := ldap.DialURL(config.LdapServerAddr)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return nil
- }
-
- if config.LdapTLS {
- err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return nil
- }
- }
-
- return l
-}
-
// Page handlers ----
+
+// --- Home Controller
type HomePageData struct {
- Login *LoginStatus
+ User *LoggedUser
BaseDN string
}
func handleHome(w http.ResponseWriter, r *http.Request) {
templateHome := getTemplate("home.html")
- login := checkLogin(w, r)
- if login == nil {
+ user := RequireUserHtml(w, r)
+ if user == nil {
return
}
data := &HomePageData{
- Login: login,
+ User: user,
BaseDN: config.BaseDN,
}
templateHome.Execute(w, data)
}
+// --- Logout Controller
func handleLogout(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, SESSION_NAME)
if err != nil {
@@ -374,9 +231,10 @@ func handleLogout(w http.ResponseWriter, r *http.Request) {
return
}
- http.Redirect(w, r, "/", http.StatusFound)
+ http.Redirect(w, r, "/login", http.StatusFound)
}
+// --- Login Controller ---
type LoginFormData struct {
Username string
WrongUser bool
@@ -384,34 +242,26 @@ type LoginFormData struct {
ErrorMessage string
}
-func buildUserDN(username string) string {
- user_dn := fmt.Sprintf("%s=%s,%s", config.UserNameAttr, username, config.UserBaseDN)
- if strings.EqualFold(username, config.AdminAccount) {
- user_dn = username
- }
-
- return user_dn
-}
-
-func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
+func handleLogin(w http.ResponseWriter, r *http.Request) {
templateLogin := getTemplate("login.html")
if r.Method == "GET" {
templateLogin.Execute(w, LoginFormData{})
- return nil
+ return
} else if r.Method == "POST" {
r.ParseForm()
username := strings.Join(r.Form["username"], "")
password := strings.Join(r.Form["password"], "")
- user_dn := buildUserDN(username)
+ loginInfo := LoginInfo { username, password }
- l := ldapOpen(w)
- if l == nil {
- return nil
+ l, err := NewLdapCon()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
}
- err := l.Bind(user_dn, password)
+ err = l.Bind(loginInfo.DN(), loginInfo.Password)
if err != nil {
data := &LoginFormData{
Username: username,
@@ -424,7 +274,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
data.ErrorMessage = err.Error()
}
templateLogin.Execute(w, data)
- return nil
+ return
}
// Successfully logged in, save it to session
@@ -435,21 +285,15 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
session.Values["login_username"] = username
session.Values["login_password"] = password
- session.Values["login_dn"] = user_dn
err = session.Save(r, w)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
- return nil
+ return
}
- return &LoginInfo{
- DN: user_dn,
- Username: username,
- Password: password,
- }
+ http.Redirect(w, r, "/", http.StatusFound)
} else {
http.Error(w, "Unsupported method", http.StatusBadRequest)
- return nil
}
}