// standardHttp starts serving standard HTTP (api/web) requests, to be used by normal clients func standardHttp(discovery bool) { m := martini.Classic() switch strings.ToLower(config.Config.AuthenticationMethod) { case "basic": { if config.Config.HTTPAuthUser == "" { // Still allowed; may be disallowed in future versions log.Warning("AuthenticationMethod is configured as 'basic' but HTTPAuthUser undefined. Running without authentication.") } m.Use(auth.Basic(config.Config.HTTPAuthUser, config.Config.HTTPAuthPassword)) } case "multi": { if config.Config.HTTPAuthUser == "" { // Still allowed; may be disallowed in future versions log.Fatal("AuthenticationMethod is configured as 'multi' but HTTPAuthUser undefined") } m.Use(auth.BasicFunc(func(username, password string) bool { if username == "readonly" { // Will be treated as "read-only" return true } return auth.SecureCompare(username, config.Config.HTTPAuthUser) && auth.SecureCompare(password, config.Config.HTTPAuthPassword) })) } default: { // We inject a dummy User object because we have function signatures with User argument in api.go m.Map(auth.User("")) } } m.Use(gzip.All()) // Render html templates from templates directory m.Use(render.Renderer(render.Options{ Directory: "resources", Layout: "templates/layout", HTMLContentType: "text/html", })) m.Use(martini.Static("resources/public")) inst.SetMaintenanceOwner(logic.ThisHostname) log.Info("Starting HTTP") if discovery { go logic.ContinuousDiscovery() } inst.ReadClusterAliases() http.API.RegisterRequests(m) http.Web.RegisterRequests(m) // Serve if err := nethttp.ListenAndServe(config.Config.ListenAddress, m); err != nil { log.Fatale(err) } }
func main() { m := martini.Classic() if !parse_args() { return } if pathcfg == "" { pathcfguser = "" } else { pathcfguser = pathcfg + string(os.PathSeparator) } m.Use(render.Renderer(render.Options{ Directory: "templates", // Specify what path to load the templates from. Layout: "layout", // Specify a layout template. Layouts can call {{ yield }} to render the current template. Extensions: []string{".tmpl", ".html"}})) m.Use(auth.BasicFunc(authFunc)) m.Get("/", indexHandler) m.Get("/addtask", AddTaskHandler) m.Get("/edit/:shop/:nstr", EditTaskHandler) m.Get("/del/:shop/:nstr", DelTaskHandler) m.Post("/exec/:shop/:nstr", ExecHandler) m.Post("/view", ViewTaskHandler) m.Get("/clickview", clickViewTaskHandler) m.Get("/", indexHandler) m.RunOnAddr(":7777") }
func main() { if conf, e := LoadConfig("conf/string_keeper.conf"); e != nil { if os.IsNotExist(e) { fmt.Println("'conf/string_keeper.conf' not exist, it will use default config.") keeperConf = DefaultConfig() } else { fmt.Printf("load config file 'conf/string_keeper.conf' failed, err: %s\n", e.Error()) os.Exit(1) } } else { keeperConf = conf } m := martini.Classic() m.Post("/", GetBucketString) m.Get("/ping", func() string { return "pong" }) if cwd, e := os.Getwd(); e != nil { fmt.Printf("get current dir failed, err: %s", e.Error()) os.Exit(1) } else if !filepath.IsAbs(cwd) { if absPath, e := filepath.Abs(cwd); e != nil { fmt.Printf("get current dir abs path failed, err: %s", e.Error()) os.Exit(1) return } else { resDir = filepath.Join(absPath, "public") } } else { resDir = filepath.Join(cwd, "public") } m.Use(cors.Allow(&cors.Options{ AllowOrigins: keeperConf.HTTP.CORS.AllowOrigins, AllowMethods: keeperConf.HTTP.CORS.AllowMethods, AllowHeaders: keeperConf.HTTP.CORS.AllowHeaders, ExposeHeaders: keeperConf.HTTP.CORS.ExposeHeaders, AllowCredentials: keeperConf.HTTP.CORS.AllowCerdentials, })) if keeperConf.ACL.AuthEnabled { m.Use(auth.BasicFunc(AuthCheck)) } else { m.Map(auth.User("")) } m.RunOnAddr(keeperConf.HTTP.Address) }
func main() { fmt.Println("Hello, let's go!") // aaa := base64.StdEncoding.EncodeToString([]byte("admin:guessme")) // fmt.Println(aaa) mongodb.Init() m := martini.Classic() m.Use(auth.BasicFunc(func(username, password string) bool { fmt.Println("username = "******"password = "******"admin") && auth.SecureCompare(password, "guessme") })) m.Use(martini.Static("client")) m.Use(martini.Static("static")) fileServer := http.FileServer(http.Dir("./static")) m.Any("/apk/**", func(res http.ResponseWriter, req *http.Request) { fmt.Println("/apk/") fileServer.ServeHTTP(res, req) }) m.Use(render.Renderer(render.Options{ Directory: "templates", Layout: "layout", Extensions: []string{".tmpl", ".html"}, })) route.Route(m) appmanager.Init() appmanager.RouteApi(m) m.Run() }
// standardHttp starts serving HTTP or HTTPS (api/web) requests, to be used by normal clients func standardHttp(discovery bool) { m := martini.Classic() switch strings.ToLower(config.Config.AuthenticationMethod) { case "basic": { if config.Config.HTTPAuthUser == "" { // Still allowed; may be disallowed in future versions log.Warning("AuthenticationMethod is configured as 'basic' but HTTPAuthUser undefined. Running without authentication.") } m.Use(auth.Basic(config.Config.HTTPAuthUser, config.Config.HTTPAuthPassword)) } case "multi": { if config.Config.HTTPAuthUser == "" { // Still allowed; may be disallowed in future versions log.Fatal("AuthenticationMethod is configured as 'multi' but HTTPAuthUser undefined") } m.Use(auth.BasicFunc(func(username, password string) bool { if username == "readonly" { // Will be treated as "read-only" return true } return auth.SecureCompare(username, config.Config.HTTPAuthUser) && auth.SecureCompare(password, config.Config.HTTPAuthPassword) })) } default: { // We inject a dummy User object because we have function signatures with User argument in api.go m.Map(auth.User("")) } } m.Use(gzip.All()) // Render html templates from templates directory m.Use(render.Renderer(render.Options{ Directory: "resources", Layout: "templates/layout", HTMLContentType: "text/html", })) m.Use(martini.Static("resources/public")) if config.Config.UseMutualTLS { m.Use(ssl.VerifyOUs(config.Config.SSLValidOUs)) } inst.SetMaintenanceOwner(process.ThisHostname) if discovery { log.Info("Starting Discovery") go logic.ContinuousDiscovery() } log.Info("Registering endpoints") http.API.RegisterRequests(m) http.Web.RegisterRequests(m) // Serve if config.Config.ListenSocket != "" { log.Infof("Starting HTTP listener on unix socket %v", config.Config.ListenSocket) unixListener, err := net.Listen("unix", config.Config.ListenSocket) if err != nil { log.Fatale(err) } defer unixListener.Close() if err := nethttp.Serve(unixListener, m); err != nil { log.Fatale(err) } } else if config.Config.UseSSL { log.Info("Starting HTTPS listener") tlsConfig, err := ssl.NewTLSConfig(config.Config.SSLCAFile, config.Config.UseMutualTLS) if err != nil { log.Fatale(err) } tlsConfig.InsecureSkipVerify = config.Config.SSLSkipVerify if err = ssl.AppendKeyPairWithPassword(tlsConfig, config.Config.SSLCertFile, config.Config.SSLPrivateKeyFile, sslPEMPassword); err != nil { log.Fatale(err) } if err = ssl.ListenAndServeTLS(config.Config.ListenAddress, m, tlsConfig); err != nil { log.Fatale(err) } } else { log.Infof("Starting HTTP listener on %+v", config.Config.ListenAddress) if err := nethttp.ListenAndServe(config.Config.ListenAddress, m); err != nil { log.Fatale(err) } } log.Info("Web server started") }
func Run(config c.QuestConfig, qs *QuestStorage, ntf *ntf.Notifier, additionalNotifier *ntf.Notifier) { m := martini.New() m.Use(w.NonJsonLogger()) m.Use(martini.Recovery()) m.Use(render.Renderer(render.Options{ Directory: "templates/quests", Layout: "layout", Extensions: []string{".tmpl", ".html"}, Charset: "UTF-8", IndentJSON: true, IndentXML: true, Funcs: []template.FuncMap{ template.FuncMap{ "eq_s": func(a, b string) bool { return a == b }, "stamp_date": func(t time.Time) string { return t.Format(time.Stamp) }, }, }, })) m.Use(auth.BasicFunc(func(username, password string) bool { pwd, ok := users[username] return ok && pwd == password })) m.Use(martini.Static("static")) r := martini.NewRouter() r.Get("/", func(user auth.User, render render.Render) { render.HTML(200, "readme", map[string]interface{}{}) }) r.Get("/new_keys", func(render render.Render) { render.HTML(200, "new_keys", GetKeysErrorInfo("", qs)) }) r.Post("/add_key", func(user auth.User, render render.Render, request *http.Request) { start_key := strings.TrimSpace(request.FormValue("start-key")) next_key := strings.TrimSpace(request.FormValue("next-key")) description := request.FormValue("description") log.Printf("QUESTS WEB add key %s -> %s -> %s", start_key, description, next_key) if start_key != "" && description != "" { key, err := qs.AddStep(start_key, description, next_key) if key != nil && err != nil { render.HTML(200, "new_keys", GetKeysErrorInfo("Такой ключ уже существует. Используйте изменение ключа если хотите его изменить.", qs)) return } } else { render.HTML(200, "new_keys", GetKeysErrorInfo("Невалидные значения ключа или ответа", qs)) return } render.Redirect("/new_keys") }) r.Post("/delete_key/:key", func(params martini.Params, render render.Render) { key := params["key"] err := qs.DeleteStep(key) log.Printf("QUESTS WEB will delete %v (%v)", key, err) render.Redirect("/new_keys") }) r.Post("/update_key/:key", func(params martini.Params, render render.Render, request *http.Request) { key_id := params["key"] start_key := strings.TrimSpace(request.FormValue("start-key")) next_key := strings.TrimSpace(request.FormValue("next-key")) description := request.FormValue("description") err := qs.UpdateStep(key_id, start_key, description, next_key) log.Printf("QUESTS WEB was update key %s %s %s %s\n err? %v", key_id, start_key, description, next_key, err) render.Redirect("/new_keys") }) r.Get("/delete_key_all", func(render render.Render) { qs.Steps.RemoveAll(bson.M{}) render.Redirect("/new_keys") }) xlsFileReg := regexp.MustCompile(".+\\.xlsx?") r.Post("/load/up", func(render render.Render, request *http.Request) { file, header, err := request.FormFile("file") log.Printf("QS: Form file information: file: %+v \nheader:%v, %v\nerr:%v", file, header.Filename, header.Header, err) if err != nil { render.HTML(200, "new_keys", GetKeysErrorInfo(fmt.Sprintf("Ошибка загрузки файлика: %v", err), qs)) return } defer file.Close() data, err := ioutil.ReadAll(file) if err != nil { render.HTML(200, "new_keys", GetKeysErrorInfo(fmt.Sprintf("Ошибка загрузки файлика: %v", err), qs)) return } if xlsFileReg.MatchString(header.Filename) { xlFile, err := xlsx.OpenBinary(data) if err != nil || xlFile == nil { render.HTML(200, "new_keys", GetKeysErrorInfo(fmt.Sprintf("Ошибка обработки файлика: %v", err), qs)) return } skip_rows, errsr := strconv.Atoi(request.FormValue("skip-rows")) skip_cols, errsc := strconv.Atoi(request.FormValue("skip-cols")) if errsr != nil || errsc != nil { render.HTML(200, "new_keys", GetKeysErrorInfo("Не могу распознать количества столбцов и строк пропускаемых :(", qs)) return } log.Printf("QS: Will process file: %+v, err: %v \n with skipped rows: %v, cols: %v", xlFile, err, skip_rows, skip_cols) parse_res, errp := w.ParseExportXlsx(xlFile, skip_rows, skip_cols) if errp != nil { render.HTML(200, "new_keys", GetKeysErrorInfo("Ошибка в парсинге файла:(", qs)) return } res, val_err := ValidateKeys(parse_res) if val_err != nil { render.HTML(200, "new_keys", GetKeysErrorInfo(val_err.Error(), qs)) return } for _, prel := range parse_res { qs.AddStep(prel[0], prel[1], prel[2]) } render.HTML(200, "new_keys", GetKeysTeamsInfo(res, qs)) } else { render.HTML(200, "new_keys", GetKeysErrorInfo("Файл имеет не то расширение :(", qs)) } render.Redirect("/new_keys") }) r.Get("/chat", func(render render.Render, params martini.Params, req *http.Request) { var with string result_data := map[string]interface{}{} query := req.URL.Query() for key, value := range query { if key == "with" && len(value) > 0 { with = value[0] log.Printf("QSERV: with found is: %v", with) break } } type Collocutor struct { IsTeam bool IsMan bool IsAll bool IsWinner bool WinTime string Info interface{} Name string } collocutor := Collocutor{} var messages []Message if with != ALL && with != ALL_TEAM_MEMBERS { if team, _ := qs.GetTeamByName(with); team != nil { type TeamInfo struct { FoundedKeys []string Members []TeamMember AllKeys []Step } collocutor.Name = team.Name collocutor.IsTeam = true collocutor.IsWinner = team.Winner if collocutor.IsWinner { tm := time.Unix(team.WinTime, 0) collocutor.WinTime = tm.Format("Mon 15:04:05") } members, _ := qs.GetMembersOfTeam(team.Name) keys, _ := qs.GetSteps(bson.M{"for_team": team.Name}) keys = SortSteps(keys) collocutor.Info = TeamInfo{FoundedKeys: team.FoundKeys, Members: members, AllKeys: keys} messages, _ = qs.GetMessages(bson.M{ "$or": []bson.M{ bson.M{"from": team.Name}, bson.M{"to": team.Name}, }, }) } else { if peoples, _ := qs.GetPeoples(bson.M{"user_id": with}); len(peoples) > 0 { man := peoples[0] collocutor.IsMan = true collocutor.Name = man.Name collocutor.Info = man messages, _ = qs.GetMessages(bson.M{ "$or": []bson.M{ bson.M{"from": man.UserId}, bson.M{"to": man.UserId}, }, }) for i, _ := range messages { if messages[i].From != ME { messages[i].From = man.Name } } } else { with = "all" } } } if strings.HasPrefix(with, "all") { collocutor.IsAll = true collocutor.Name = with messages, _ = qs.GetMessages(bson.M{"to": with}) } //log.Printf("QS i return this messages: %+v", messages) result_data["with"] = with result_data["collocutor"] = collocutor if len(messages) > 100 { messages = messages[0:100] } result_data["messages"] = messages qs.SetMessagesRead(with) all_teams, _ := qs.GetAllTeams() if contacts, err := qs.GetContacts(all_teams); err == nil { result_data["contacts"] = contacts } render.HTML(200, "chat", result_data) }) r.Post("/send", func(render render.Render, req *http.Request) { type MessageFromF struct { From string `json:"from"` To string `json:"to"` Body string `json:"body"` } data, err := ioutil.ReadAll(req.Body) if err != nil { log.Printf("QS QE E: errror at reading req body %v", err) render.JSON(500, map[string]interface{}{"error": err}) return } message := MessageFromF{} err = json.Unmarshal(data, &message) if err != nil { log.Printf("QS QE E: at unmarshal json messages %v\ndata:%s", err, data) render.JSON(500, map[string]interface{}{"error": err}) return } log.Printf("QS I see this data for send message from f:\n %+v", message) var result Message if message.From != "" && message.To != "" && message.Body != "" { if message.To == "all" { peoples, _ := qs.GetPeoples(bson.M{}) log.Printf("QSERV: will send [%v] to all %v peoples", message.Body, len(peoples)) SendMessagesToPeoples(peoples, ntf, message.Body) } else if message.To == "all_team_members" { peoples, _ := qs.GetAllTeamMembers() log.Printf("QSERV: will send [%v] to all team members %v peoples", message.Body, len(peoples)) SendMessagesToPeoples(peoples, ntf, message.Body) } else { team, _ := qs.GetTeamByName(message.To) if team == nil { man, _ := qs.GetManByUserId(message.To) if man != nil { log.Printf("QSERV: will send [%v] to %v", message.Body, man.UserId) go ntf.NotifyText(man.UserId, message.Body) } } else { peoples, _ := qs.GetMembersOfTeam(team.Name) log.Printf("QSERV: will send [%v] to team members of %v team to %v peoples", message.Body, team.Name, len(peoples)) SendMessagesToPeoples(peoples, ntf, message.Body) } } result, err = qs.StoreMessage(message.From, message.To, message.Body, false) if err != nil { log.Printf("QSERV: error at storing message %v", err) render.JSON(200, map[string]interface{}{"ok": false}) return } result.TimeFormatted = result.Time.Format(time.Stamp) } else { render.JSON(200, map[string]interface{}{"ok": false}) } render.JSON(200, map[string]interface{}{"ok": true, "message": result}) }) r.Post("/messages", func(render render.Render, req *http.Request) { type NewMessagesReq struct { For string `json:"m_for"` After int64 `json:"after"` } q := NewMessagesReq{} request_body, err := ioutil.ReadAll(req.Body) if err != nil { render.JSON(500, map[string]interface{}{"ok": false, "detail": "can not read request body"}) return } err = json.Unmarshal(request_body, &q) if err != nil { render.JSON(500, map[string]interface{}{"ok": false, "detail": fmt.Sprintf("can not unmarshal request body %v \n %s", err, request_body)}) return } messages, err := qs.GetMessages(bson.M{"from": q.For, "time_stamp": bson.M{"$gt": q.After}}) if err != nil { render.JSON(500, map[string]interface{}{"ok": false, "detail": fmt.Sprintf("error in db: %v", err)}) return } for i, message := range messages { team, _ := qs.GetTeamByName(message.From) if team != nil { messages[i].From = team.Name } else { man, _ := qs.GetManByUserId(message.From) if man != nil { messages[i].From = man.Name } } messages[i].TimeFormatted = message.Time.Format(time.Stamp) } render.JSON(200, map[string]interface{}{"messages": messages, "next_": time.Now().Unix()}) }) r.Post("/contacts", func(render render.Render, req *http.Request) { type NewContactsReq struct { After int64 `json:"after"` Exist []string `json:"exist"` } cr := NewContactsReq{} request_body, err := ioutil.ReadAll(req.Body) if err != nil { render.JSON(500, map[string]interface{}{"ok": false, "detail": "can not read request body"}) return } err = json.Unmarshal(request_body, &cr) if err != nil { render.JSON(500, map[string]interface{}{"ok": false, "detail": fmt.Sprintf("can not unmarshal request body %v \n %s", err, request_body)}) return } contacts, err := qs.GetContactsAfter(cr.After) if err != nil { render.JSON(500, map[string]interface{}{"ok": false, "detail": err}) return } new_contacts := []Contact{} old_contacts := []Contact{} for _, contact := range contacts { if utils.InS(contact.ID, cr.Exist) { old_contacts = append(old_contacts, contact) } else { new_contacts = append(new_contacts, contact) } } render.JSON(200, map[string]interface{}{ "ok": true, "new": new_contacts, "old": old_contacts, "next_": time.Now().Unix(), }) }) r.Get("/manage", func(render render.Render, req *http.Request) { configResult, err := qs.GetMessageConfiguration(config.Chat.CompanyId) if err != nil { log.Printf("QS E: Can not load quest configuration for %v, because: %v", config.Chat.CompanyId, err) } render.HTML(200, "manage", map[string]interface{}{"config": configResult}) }) r.Post("/manage", binding.Bind(QuestMessageConfiguration{}), func(qmc QuestMessageConfiguration, ren render.Render, req *http.Request) { if req.FormValue("to-winner-on") == "on" { qmc.EndMessageForWinnersActive = true } if req.FormValue("to-not-winner-on") == "on" { qmc.EndMessageForNotWinnersActive = true } if req.FormValue("to-all-on") == "on" { qmc.EndMessageForAllActive = true } log.Printf("QS Manage: %+v", qmc) qmc.CompanyId = config.Chat.CompanyId err := qs.SetMessageConfiguration(qmc, true) if err != nil { log.Printf("QS ERROR at update quest message configuration for [%v], because: %v", qmc.CompanyId, err) } ren.Redirect("/manage", 302) }) r.Post("/start_quest", func(ren render.Render) { qmc, err := qs.GetMessageConfiguration(config.Chat.CompanyId) if err != nil { log.Printf("QS E: Can not load quest configuration for %v, because: %v", config.Chat.CompanyId, err) ren.JSON(500, map[string]interface{}{"ok": false, "detail": err}) return } if qmc.Started == false { qs.SetQuestStarted(config.Chat.CompanyId, true) ren.JSON(200, map[string]interface{}{"ok": true}) } else { ren.JSON(200, map[string]interface{}{"ok": false, "detail": "already started"}) } }) r.Post("/stop_quest", func(ren render.Render) { qmc, err := qs.GetMessageConfiguration(config.Chat.CompanyId) if err != nil { log.Printf("QS E: Can not load quest configuration for %v, because: %v", config.Chat.CompanyId, err) ren.JSON(500, map[string]interface{}{"ok": false, "detail": err}) return } if qmc.Started == true { qs.SetQuestStarted(config.Chat.CompanyId, false) teams, err := qs.GetAllTeams() if err != nil { log.Printf("QS QE E: errror at getting teams %v", err) } if qmc.EndMessageForAllActive == true { for _, team := range teams { log.Printf("QS Will send message to team: %v from Klichat", team.Name) members, _ := qs.GetMembersOfTeam(team.Name) SendMessagesToPeoples(members, additionalNotifier, qmc.EndMessageForAll) } } if qmc.EndMessageForWinnersActive == true { for _, team := range teams { if team.Winner == true { log.Printf("QS Will send WIN message to team: %v from quest", team.Name) members, _ := qs.GetMembersOfTeam(team.Name) SendMessagesToPeoples(members, ntf, qmc.EndMessageForWinners) } } } if qmc.EndMessageForNotWinnersActive == true { for _, team := range teams { if team.Winner == false { log.Printf("QS Will send NOT WIN message to team: %v from quest", team.Name) members, _ := qs.GetMembersOfTeam(team.Name) SendMessagesToPeoples(members, ntf, qmc.EndMessageForNotWinners) } } } ren.JSON(200, map[string]interface{}{"ok": true}) } else { ren.JSON(200, map[string]interface{}{"ok": false, "detail": "already stopped"}) } }) r.Get("/delete_chat/:between", func(params martini.Params, render render.Render, req *http.Request) { between := params["between"] qs.Messages.RemoveAll(bson.M{"$or": []bson.M{bson.M{"from": between}, bson.M{"to": between}}}) render.Redirect(fmt.Sprintf("/chat?with=%v", between)) }) r.Post("/send_messages_at_quest_end", func(render render.Render, req *http.Request) { type Messages struct { Text string `json:"text"` Teams []string `json:"teams"` Exclude bool `json:"exclude"` } messages := Messages{} data, err := ioutil.ReadAll(req.Body) if err != nil { log.Printf("QS QE E: errror at reading req body %v", err) render.JSON(500, map[string]interface{}{"error": err}) return } err = json.Unmarshal(data, &messages) if err != nil { log.Printf("QS QE E: at unmarshal json messages %v", err) render.JSON(500, map[string]interface{}{"error": err}) return } log.Printf("QS I see this data for send messages at quest end:\n %+v", messages) if messages.Exclude { teams, err := qs.GetAllTeams() if err != nil { log.Printf("QS QE E: errror at getting teams %v", err) render.JSON(500, map[string]interface{}{"error": err}) return } for _, team := range teams { if !utils.InS(team.Name, messages.Teams) { log.Printf("QS Will send message to team: %v", team.Name) members, _ := qs.GetMembersOfTeam(team.Name) SendMessagesToPeoples(members, additionalNotifier, messages.Text) } } render.JSON(200, map[string]interface{}{"ok": true}) } else { for _, team_name := range messages.Teams { members, err := qs.GetMembersOfTeam(team_name) if err != nil { log.Printf("QS QE E: errror at getting team members %v", err) continue } log.Printf("QS Will send message to team: %v", team_name) SendMessagesToPeoples(members, additionalNotifier, messages.Text) } render.JSON(200, map[string]interface{}{"ok": true}) } }) r.Post("/delete_all_keys", func(render render.Render, req *http.Request) { //1. Steps or keys: si, _ := qs.Steps.RemoveAll(bson.M{}) //2 Peoples pi, _ := qs.Peoples.UpdateAll(bson.M{ "$and": []bson.M{ bson.M{"$or": []bson.M{ bson.M{"is_passerby": false}, bson.M{"is_passerby": bson.M{"$exists": false}}, }}, bson.M{"$or": []bson.M{ bson.M{"team_name": bson.M{"$exists": true}}, bson.M{"team_sid": bson.M{"$exists": true}}, }}, }, }, bson.M{ "$set": bson.M{"is_passerby": true}, "$unset": bson.M{"team_name": "", "team_sid": ""}, }) //3 teams and messages teams := []Team{} qs.Teams.Find(bson.M{}).All(&teams) tc := 0 mc := 0 for _, team := range teams { mri, _ := qs.Messages.RemoveAll(bson.M{ "$or": []bson.M{ bson.M{"from": team.Name}, bson.M{"to": team.Name}, }}) mc += mri.Removed qs.Teams.RemoveId(team.ID) tc += 1 } render.JSON(200, map[string]interface{}{ "ok": true, "steps_removed": si.Removed, "peoples_updated": pi.Updated, "teams_removed": tc, "messages_removed": mc, }) }) r.Post("/founded_keys", func(ren render.Render, req *http.Request) { type T struct { Name string `json:"team"` } t := T{} body, _ := ioutil.ReadAll(req.Body) json.Unmarshal(body, &t) steps, _ := qs.GetSteps(bson.M{"for_team": t.Name, "is_found": true}) ren.JSON(200, map[string]interface{}{"keys": steps}) }) type FoundKey struct { Name string `bson:"name" json:"name"` Found bool `bson:"found" json:"found"` Id string `json:"id"` Description string `json:"description"` } type TeamInfo struct { TeamName string `bson:"team_name" json:"team_name"` Keys []FoundKey `json:"keys"` Steps []Step `bson:"steps"` } r.Get("/info_page", func(ren render.Render, req *http.Request) { result := []TeamInfo{} err := qs.Steps.Pipe([]bson.M{ bson.M{"$group": bson.M{ "_id": "$for_team", "team_name": bson.M{"$first": "$for_team"}, "steps": bson.M{"$push": bson.M{ "_id": "$_id", "is_found": "$is_found", "next_key": "$next_key", "start_key": "$start_key", "description": "$description", }}}}, bson.M{"$sort": bson.M{ "team_name": 1}}, }).All(&result) if err != nil { log.Printf("QS Error at aggregate info page %v", err) } for ti, teamInfo := range result { steps := SortSteps(teamInfo.Steps) keys := []FoundKey{} for _, step := range steps { keys = append(keys, FoundKey{Name: step.StartKey, Found: step.IsFound, Id: step.ID.Hex(), Description: step.Description}) } result[ti].Keys = keys result[ti].Steps = []Step{} } ren.HTML(200, "info_page", map[string]interface{}{"teams": result}) }) r.Post("/info_page/update", func(ren render.Render, req *http.Request) { found_keys, err := qs.GetSteps(bson.M{"is_found": true}) if err != nil { ren.JSON(500, map[string]interface{}{"ok": false, "error": err.Error()}) } type UpdateKeyResult struct { Id string `json:"id"` } result := []UpdateKeyResult{} for _, key := range found_keys { result = append(result, UpdateKeyResult{Id: key.ID.Hex()}) } ren.JSON(200, map[string]interface{}{"ok": true, "foundKeys": result}) }) r.Post("/start_quest", func(ren render.Render, req *http.Request) { ren.JSON(200, map[string]interface{}{"ok": true}) }) r.Post("/stop_quest") //m.MapTo(r, (*martini.Routes)(nil)) log.Printf("Will start web server for quest at: %v", config.WebPort) m.Action(r.Handle) m.RunOnAddr(config.WebPort) }
func LdapAuthenticator(options *LdapOptions) (martini.Handler, error) { hostInfo := HostExpr.FindStringSubmatch(options.Host) config := &ldapConfig{} switch hostInfo[1] { case "ldap": config.SSL = false case "ldaps": config.SSL = true default: return nil, fmt.Errorf("invalid ldap protocol: %s", hostInfo[1]) } config.Host = hostInfo[2] if hostInfo[4] != "" { port, err := strconv.ParseUint(hostInfo[4], 10, 16) if err != nil { return nil, fmt.Errorf("unable to parse ldap port: %s", err) } config.Port = uint16(port) } else { if config.SSL { config.Port = 636 } else { config.Port = 389 } } return func(res http.ResponseWriter, req *http.Request, c martini.Context, log *log.Logger) { // HACK TODO: do not put routing logic in the auth handler // The /ping endpoint does not have auth, so explicitly exclude it here if req.URL.Path == "/ping" { return } authHandler := auth.BasicFunc(func(username, password string) bool { // create the ldap server connection var conn *ldap.LDAPConnection if config.SSL { tlsConfig := tls.Config{ ServerName: config.Host, } conn = ldap.NewLDAPSSLConnection(config.Host, config.Port, &tlsConfig) } else { conn = ldap.NewLDAPConnection(config.Host, config.Port) } // attempt to connect to the ldap server if err := conn.Connect(); err != nil { log.Printf("Unable to connect to LDAP: %s", err) return false } // perform an anonymous search for the user's dn so we can attempt to bind as them req := ldap.SearchRequest{ BaseDN: options.BaseDN, Filter: fmt.Sprintf(options.UserFilter, ldap.EscapeFilterValue(username)), Scope: ldap.ScopeWholeSubtree, } res, err := conn.Search(&req) if err != nil { log.Printf("Error performing LDAP search: %s", err) return false } // Return false if the number of entries isn't exactly 1. If multiple // results were returned, there is an ambiguity so return false instead // of proceeding. If no entries were returned, we have no idea who this // is and cannot authenticate. if len(res.Entries) != 1 { if len(res.Entries) > 1 { log.Printf("User '%s' attempted to authenticate but multiple entries exists", username) } else { log.Printf("User '%s' attempted to authenticate but does not exist", username) } return false } dn := res.Entries[0].DN if err := conn.Bind(dn, password); err != nil { log.Printf("User '%s' attempted to authenticate but provided an invalid password", username) return false } log.Printf("Authenticated successfully as %s", username) return true }) authenticate := authHandler.(func(http.ResponseWriter, *http.Request, martini.Context)) authenticate(res, req, c) }, nil }