Beispiel #1
0
// 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)
	}
}
Beispiel #2
0
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")

}
Beispiel #3
0
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)
}
Beispiel #4
0
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()
}
Beispiel #5
0
// 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)
}
Beispiel #7
0
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
}