diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 224 |
1 files changed, 47 insertions, 177 deletions
@@ -2,10 +2,8 @@ package main import ( "crypto/rand" - "crypto/tls" "encoding/json" "flag" - "fmt" "html/template" "io/ioutil" "log" @@ -58,7 +56,8 @@ type ConfigFile struct { S3Bucket string `json:"s3_bucket"` } -var configFlag = flag.String("config", "./config.json", "Configuration file path") +var fsServer = flag.NewFlagSet("server", flag.ContinueOnError) +var configFlag = fsServer.String("config", "./config.json", "Configuration file path") var config *ConfigFile @@ -114,8 +113,25 @@ func getTemplate(name string) *template.Template { } func main() { - flag.Parse() + if len(os.Args) < 2 { + server(os.Args[1:]) + return + } + + switch os.Args[1] { + case "cli": + cliMain(os.Args[2:]) + case "server": + server(os.Args[2:]) + default: + log.Println("Usage: guichet [server|cli] --help") + os.Exit(1) + } +} +func server(args []string) { + log.Println("Starting Guichet Server") + fsServer.Parse(args) config_file := readConfig() config = &config_file @@ -128,8 +144,12 @@ func main() { r := mux.NewRouter() r.HandleFunc("/", handleHome) + r.HandleFunc("/login", handleLogin) r.HandleFunc("/logout", handleLogout) + r.HandleFunc("/api/unstable/website", handleAPIWebsiteList) + r.HandleFunc("/api/unstable/website/{bucket}", handleAPIWebsiteInspect) + r.HandleFunc("/profile", handleProfile) r.HandleFunc("/passwd", handlePasswd) r.HandleFunc("/picture/{name}", handleDownloadPicture) @@ -137,10 +157,10 @@ func main() { 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("/website", handleWebsiteList) + r.HandleFunc("/website/new", handleWebsiteNew) + r.HandleFunc("/website/configure", handleWebsiteConfigure) + r.HandleFunc("/website/inspect/{bucket}", handleWebsiteInspect) r.HandleFunc("/invite/new_account", handleInviteNewAccount) r.HandleFunc("/invite/send_code", handleInviteSendCode) @@ -163,31 +183,6 @@ func main() { } } -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) @@ -195,149 +190,31 @@ 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 { @@ -354,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 @@ -364,28 +242,26 @@ type LoginFormData struct { ErrorMessage string } -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 := fmt.Sprintf("%s=%s,%s", config.UserNameAttr, username, config.UserBaseDN) - if strings.EqualFold(username, config.AdminAccount) { - user_dn = 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, @@ -398,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 @@ -409,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 } } |