// Creates a new user func Register(w http.ResponseWriter, req *http.Request) { if req.Method == "POST" { req.ParseForm() passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.FormValue("password")), bcrypt.DefaultCost) if err != nil { panic(err) } u := &models.User{ Firstname: sPtr(req.FormValue("firstname")), Surname: sPtr(req.FormValue("surname")), Mail: sPtr(req.FormValue("mail")), Password: sPtr(string(passwordHash)), } errs := u.Validate() if len(errs) > 0 { logs.Debug(errs) return } var store = models.UserStore(getDB(req)) err = store.Save(u) if err != nil { logs.Error(err) return } } templates := getTemplates(req) if err := templates["users/register"].ExecuteTemplate(w, "base", nil); err != nil { logs.Error(err) } }
// Middleware that takes care of the authentication. If the token is not correct or there is no token, an error is returned func Authenticate(h http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { // Pour desactiver l'authentification // router.Context(r).Env["GroupID"] = uint(1) // router.Context(r).Env["UserID"] = uint(1) // h.ServeHTTP(w, r) // return // token := strings.TrimLeft(r.Header.Get("Authorization"), "Bearer ") if token == "" { logs.Debug("No token found") Fail(w, r, "missing bearer authorization token", http.StatusBadRequest) } else { body, _ := Bearer(r, "OAuth2", "/oauth2/info", token) resp := make(map[string]interface{}) if err := json.Unmarshal(body, &resp); err != nil { logs.Error(err) Fail(w, r, map[string]string{"Authentication": err.Error()}, http.StatusBadRequest) return } if resp["error"] != nil { // refresh := strings.TrimLeft(r.Header.Get("Refresh"), "Refresh ") // r.Form = make(url.Values) // r.Form.Add("grant_type", "refresh_token") // r.Form.Add("refresh_token", refresh) // logs.Debug(refresh) // body, _ := ServiceBody(PostMethod, r, "OAuth2", "/oauth2/token", "application/x-www-form-urlencoded", []byte(r.Form.Encode())) // resp := make(map[string]interface{}) // if err := json.Unmarshal(body, &resp); err != nil { // logs.Error(err) // Fail(w, r, map[string]string{"Authentication": err.Error()}, http.StatusBadRequest) // return // } // logs.Debug(resp) // if resp["error"] != nil { logs.Debug("Token expired") Fail(w, r, "Token", http.StatusBadRequest) // } } else { s := strings.Split(resp["owner"].(string), ":") ID, _ := strconv.Atoi(s[0]) groupID, _ := strconv.Atoi(s[1]) router.Context(r).Env["GroupID"] = uint(groupID) router.Context(r).Env["UserID"] = uint(ID) if ID == 0 { logs.Error(errors.New("ID is 0, no such user")) Fail(w, r, map[string]string{"ID": "is 0"}, http.StatusBadRequest) return } logs.Debug("Authentication done") h.ServeHTTP(w, r) } } } return http.HandlerFunc(fn) }
func UpdateUser(w http.ResponseWriter, req *http.Request) { //logs.Debug("on rentre dans RegisterUser") req.ParseForm() if req.FormValue("mail") != "" && req.FormValue("password") != "" { // Perform an OAuth "Resource Owner Password Credentials Grant" req.Form.Add("grant_type", "password") body, err := ServiceBody(PostMethod, req, "OAuth2", "/users/update", "application/x-www-form-urlencoded", []byte(req.Form.Encode())) if err != nil { logs.Error(err) jsonapi.Error(w, req, err.Error(), http.StatusInternalServerError) return } else { logs.Debug("on passe successfull dans UpdateUser de Gateway/controllers/session.go") } // Check http status for errors var t StructRegisterUser err = json.Unmarshal(body, &t) if err != nil { } else { jsonapi.Error(w, req, t.Message, http.StatusBadRequest) } } }
// RetrieveGroup calls the GroupSQL First method and returns the results func RetrieveGroup(w http.ResponseWriter, r *http.Request) { id, err := strconv.Atoi(router.Context(r).Param("id")) if err != nil { logs.Debug(err) Fail(w, r, map[string]interface{}{"id": "not integer"}, http.StatusBadRequest) return } var ( g = models.Group{} db = getDB(r) groupStore = models.GroupStore(db) ) if err = groupStore.First(&g, uint(id)); err != nil { if err == sql.ErrNoRows { Fail(w, r, nil, http.StatusNotFound) return } logs.Error(err) Error(w, r, err.Error(), http.StatusInternalServerError) return } Success(w, r, views.Group{Group: &g}, http.StatusOK) }
func serve(ctx *cli.Context) error { var app = application.New() config, err := settings.Parse(ctx.String("config")) if err != nil && ctx.String("config") != "" { logs.Error(err) } if ctx.Bool("debug") || config.Debug() { logs.Level(logs.DebugLevel) } app.Components["Mux"] = router.New() if ctx.Bool("debug") || config.Debug() { app.Use(router.Logger) } app.Use(app.Apply) app.Post("/trigger/:id", controllers.TriggerBuild) server, err := config.Server() if err != nil { logs.Critical(err) os.Exit(1) } return app.Serve(server.String()) }
// Returns the group informations using his authentication token. Calls Oauth2 via HTTP. Returns results via jsonapi. func RetrieveGroup(w http.ResponseWriter, r *http.Request) { ID := router.Context(r).Env["GroupID"].(uint) path := fmt.Sprintf("/groups/%d", ID) body, _ := Service(GetMethod, r, "OAuth2", path) resp := make(map[string]interface{}) if err := json.Unmarshal(body, &resp); err != nil { logs.Error(err) Fail(w, r, map[string]string{"Authentication": "Could not join the server"}, http.StatusBadRequest) return } if resp["error"] != nil { Fail(w, r, resp["error_description"], http.StatusBadRequest) } else { resp = resp["data"].(map[string]interface{}) resp = resp["group"].(map[string]interface{}) //UID := int64(resp["id"].(float64)) GID := uint(resp["id"].(float64)) NAME := sPtr(resp["name"].(string)) Date := time.Now() if resp["endofcampain"] != nil { datecampain := resp["endofcampain"].(string) Date, _ = time.Parse(time.RFC3339, datecampain) } g := usermodels.Group{ID: GID, Name: NAME, Endofcampain: &Date} // Success(w, r, userviews.Group{Group: &g}, http.StatusOK) //g := usermodels.Group{ID: GID, Name: NAME} SuccessOKOr404(w, r, userviews.Group{Group: &g}) } }
// Index indexes a contact into elasticsearch func index(Contact *models.Contact, s *elastic.Client) error { id := strconv.Itoa(int(Contact.ID)) if id == "" { logs.Error("id is nil") return errors.New("id is nil") } if Contact.Address.Longitude == "null" || Contact.Address.Latitude == "null" { logs.Debug("Could not index contact %s", id) return nil } if Contact.Address.Latitude != "" && Contact.Address.Longitude != "" { Contact.Address.Location = fmt.Sprintf("%s,%s", Contact.Address.Latitude, Contact.Address.Longitude) } _, err := s.Index(). Index("contacts"). Type("contact"). Id(id). BodyJson(Contact). Do() if err != nil { logs.Critical(err) return err } logs.Debug("Contact %s indexed", id) return nil }
// UpdateGroup calls the GroupSQL Save method and returns the results func UpdateGroup(w http.ResponseWriter, r *http.Request) { var ( groupID int err error ) if groupID, err = strconv.Atoi(router.Context(r).Param("id")); err != nil { logs.Debug(err) Fail(w, r, map[string]interface{}{"id": "not integer"}, http.StatusBadRequest) return } var ( db = getDB(r) groupStore = models.GroupStore(db) g = &models.Group{ID: uint(groupID)} ) if err = groupStore.First(g, g.ID); err != nil { Fail(w, r, map[string]interface{}{"group": err.Error()}, http.StatusBadRequest) return } if err = Request(&views.Group{Group: g}, r); err != nil { logs.Debug(err) Fail(w, r, map[string]interface{}{"group": err.Error()}, http.StatusBadRequest) return } if err = groupStore.Save(g); err != nil { logs.Error(err) Error(w, r, err.Error(), http.StatusInternalServerError) return } Success(w, r, views.Group{Group: g}, http.StatusOK) }
// Generates a authentication token, stores it in a Redis instance under a new id and stores the id in a cookie on the user's browser to allow the gateway to later retrieve the token from the cookie and authenticate the user func Session(w http.ResponseWriter, req *http.Request) { req.ParseForm() if req.FormValue("username") != "" && req.FormValue("password") != "" { // Perform an OAuth "Resource Owner Password Credentials Grant" req.Form.Add("grant_type", "password") body, err := ServiceBody(PostMethod, req, "OAuth2", "/oauth2/token", "application/x-www-form-urlencoded", []byte(req.Form.Encode())) if err != nil { logs.Error(err) return } // TODO: Check http status for errors access := new(components.AccessData) if err := json.Unmarshal(body, access); err != nil { logs.Error(err) jsonapi.Error(w, req, err.Error(), http.StatusBadRequest) return } if access.AccessToken == "" { var err = errors.New("wrong identifiers") logs.Error(err) jsonapi.Fail(w, req, err.Error(), http.StatusBadRequest) return } session := &components.Session{ ID: strings.TrimRight(base64.StdEncoding.EncodeToString(uuid.NewRandom()), "="), AccessToken: access.AccessToken, RefreshToken: access.RefreshToken, ExpiresIn: access.ExpiresIn, } app := router.Context(req).Env["Application"].(*application.Application) store := app.Components["Redis"].(*components.RedisStore) if err := store.Save(session); err != nil { logs.Error(err) jsonapi.Error(w, req, err.Error(), http.StatusBadRequest) return } cookie := &http.Cookie{Name: "SID", Value: session.ID, Expires: time.Now().Add(356 * 24 * time.Hour)} http.SetCookie(w, cookie) jsonapi.Success(w, req, "", http.StatusOK) fmt.Println(cookie) } else { jsonapi.Error(w, req, "Bad Request", http.StatusBadRequest) } }
// Issues a DELETE HTTP request to Oauth2 func DeleteOAuth(w http.ResponseWriter, r *http.Request) { body, err := Service(DeleteMethod, r, "OAsuth2", r.URL.Path) if err != nil { logs.Error(err) return } w.Write(body) }
func serve(ctx *cli.Context) error { var err error var config settings.Config if ctx.String("config") != "" { config, err = settings.Parse(ctx.String("config")) if err != nil { logs.Error(err) } } if config.Debug() { logs.Level(logs.DebugLevel) } dialect, args, err := config.SqlDB() if err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("database type: %s", dialect) var app = application.New() if app.Components["DB"], err = databases.InitGORM(dialect, args); err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("connected to %s", args) if config.Migrate() { app.Components["DB"].(*gorm.DB).AutoMigrate(models.Models()...) logs.Debug("database migrated successfully") } app.Components["Templates"] = views.Templates() // app.Components["Mux"] = router.New() app.Components["Mux"] = gojimux.New() if config.Debug() { app.Use(router.Logger) } app.Use(app.Apply) app.Get("/users/register", controllers.Register) app.Post("/users/auth", controllers.Auth) app.Post("/users/register", controllers.Register) server, err := config.Server() if err != nil { logs.Critical(err) os.Exit(1) } return app.Serve(server.String()) }
// Deletes the cookie on the user's browser, allows him to logout func DeleteSession(w http.ResponseWriter, req *http.Request) { cookie, err := req.Cookie("SID") if err == nil { app := router.Context(req).Env["Application"].(*application.Application) store := app.Components["Redis"].(*components.RedisStore) err := store.Delete(cookie.Value) if err != nil { logs.Error(err) jsonapi.Error(w, req, err.Error(), http.StatusBadRequest) return } cookie := &http.Cookie{Name: "SID", Value: cookie.Value, Expires: time.Now()} http.SetCookie(w, cookie) jsonapi.Success(w, req, "", http.StatusOK) logs.Debug("Cookie deleted") } else { logs.Error(err) } }
func Auth(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { logs.Error(err) Fail(w, r, map[string]string{"Authentification": "Error"}, http.StatusBadRequest) return } infos := make(map[string]interface{}) if err := json.Unmarshal(body, &infos); err != nil { logs.Error(err) Fail(w, r, map[string]string{"Authentification": "Bad parameters"}, http.StatusBadRequest) return } username := infos["username"].(string) password := infos["password"].(string) passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { panic(err) } var ( u = models.User{Mail: &username, Password: sPtr(string(passwordHash))} db = getDB(r) userStore = models.UserStore(db) ) if err = userStore.First(&u); err != nil { logs.Error(err) Error(w, r, err.Error(), http.StatusInternalServerError) return } if u.GroupID == 0 { Fail(w, r, map[string]interface{}{"User": "******"}, http.StatusBadRequest) return } Success(w, r, views.User{User: &u}, http.StatusOK) }
// RetrieveGroupCollection calls the GroupSQL Find method and returns the results func RetrieveGroupCollection(w http.ResponseWriter, r *http.Request) { var ( err error groups []models.Group db = getDB(r) groupStore = models.GroupStore(db) ) if groups, err = groupStore.Find(); err != nil { logs.Error(err) Error(w, r, err.Error(), http.StatusInternalServerError) return } Success(w, r, views.Groups{Groups: groups}, http.StatusOK) }
// CreateContact calls the Create method from Contacts via RPC (Contact client) and then calls the Index method from Contacts via RPC (Search client). Returns results via jsonapi. func CreateContact(w http.ResponseWriter, r *http.Request) { var ( args = models.ContactArgs{Contact: &models.Contact{GroupID: router.Context(r).Env["GroupID"].(uint)}} //dataGEO = models.Ban{} ) if err := Request(&views.Contact{Contact: args.Contact}, r); err != nil { logs.Error(err) Fail(w, r, map[string]interface{}{"contact": err.Error()}, http.StatusBadRequest) return } var ( contactClient = rpcClient(r, "ContactClient") reply = models.ContactReply{} ) var coordonnees [2]string coordonnees = Geoloc(&args) if coordonnees[0] == "noresponse" { err := errors.New("noresponse") Error(w, r, err.Error(), http.StatusBadRequest) return } args.Contact.Address.Latitude = coordonnees[0] args.Contact.Address.Longitude = coordonnees[1] err := contactClient.Call("Contact.Create", args, &reply) if err != nil { Error(w, r, err.Error(), http.StatusInternalServerError) return } rep := models.ContactReply{} args.Contact = reply.Contact err = contactClient.Call("Search.Index", args, &rep) if err != nil { Error(w, r, err.Error(), http.StatusInternalServerError) return } Success(w, r, views.Contact{Contact: reply.Contact}, http.StatusOK) }
// Authorize endpoint func Authorize(w http.ResponseWriter, r *http.Request) { server := OAuthComponent(r) resp := server.NewResponse() defer resp.Close() if ar := server.HandleAuthorizeRequest(resp, r); ar != nil { if !example.HandleLoginPage(ar, w, r) { return } ar.UserData = "test" // Get user_id ar.Authorized = true server.FinishAuthorizeRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { logs.Error(resp.InternalError.Error()) } osin.OutputJSON(resp, w, r) }
// Returns the user informdataations using his authentication token. Calls Oauth2 via HTTP. Returns results via jsonapi. func RetrieveSelf(w http.ResponseWriter, r *http.Request) { ID := router.Context(r).Env["UserID"].(uint) path := fmt.Sprintf("/users/%d", ID) body, _ := Service(GetMethod, r, "OAuth2", path) resp := make(map[string]interface{}) if err := json.Unmarshal(body, &resp); err != nil { logs.Error(err) Fail(w, r, map[string]string{"Authentication": "Could not join the server"}, http.StatusBadRequest) return } if resp["error"] != nil { Fail(w, r, resp["error_description"], http.StatusBadRequest) } else { resp = resp["data"].(map[string]interface{}) resp = resp["user"].(map[string]interface{}) UID := int64(resp["id"].(float64)) GID := uint(resp["group_id"].(float64)) u := usermodels.User{ID: UID, GroupID: GID, Mail: sPtr(resp["Mail"].(string)), Firstname: sPtr(resp["firstname"].(string)), Surname: sPtr(resp["surname"].(string))} SuccessOKOr404(w, r, userviews.User{User: &u}) } }
// Returns the user infos from the database using the credentials func getUserInfos(username string, password string, r *http.Request) (string, error) { var ( u = models.User{Mail: &username, Password: sPtr(password)} db = getDB(r) userStore = models.UserStore(db) ) if err := userStore.First(&u); err != nil { logs.Error(err) return "0", err } if u.ID == 0 { return "0", errors.New("no such user") } if err := bcrypt.CompareHashAndPassword([]byte(*u.Password), []byte(password)); err != nil { return "0", errors.New("wrong password") } userInfos := fmt.Sprintf("%d:%d", u.ID, u.GroupID) return userInfos, nil }
// We need a retry because elasticsearch takes a bit of time to be up and running before we can connect to it func dialElasticRetry(address string) (*elastic.Client, error) { var client *elastic.Client var err error var i int retry: for { client, err = elastic.NewClient(elastic.SetURL(address)) switch { case err == nil: break retry case i >= RETRY: return nil, err default: logs.Error(err) i++ } time.Sleep(TIMEOUT) } return client, nil }
// Index indexes a contact into elasticsearch func index(Contact *models.Contact, s *elastic.Client) error { id := strconv.Itoa(int(Contact.ID)) if id == "" { logs.Error("id is nil") return errors.New("id is nil") } _, err := s.Index(). Index("contacts"). Type("contact"). Id(id). BodyJson(Contact). Do() if err != nil { logs.Critical(err) return err } logs.Debug("Indexed") return nil }
// RetrieveContactcollectionViaElastic calls the RetrieveContacts method from Contacts via RPC (Search client). Returns results via jsonapi. func RetrieveContactCollectionViaElastic(w http.ResponseWriter, r *http.Request) { var ( contactClient = rpcClient(r, "ContactClient") args = models.SearchArgs{} reply = models.SearchReply{} ) args.Search = new(models.Search) args.Search.Query = router.Context(r).Param("query") err := contactClient.Call("Search.RetrieveContacts", args, &reply) if err != nil { logs.Error(err) Error(w, r, err.Error(), http.StatusInternalServerError) return } if reply.Contacts == nil { reply.Contacts = make([]models.Contact, 0) } Success(w, r, views.Contacts{Contacts: reply.Contacts}, http.StatusOK) }
// Token endpoint func Token(w http.ResponseWriter, r *http.Request) { var ( server = OAuthComponent(r) resp = server.NewResponse() ) defer resp.Close() if ar := server.HandleAccessRequest(resp, r); ar != nil { switch ar.Type { case osin.AUTHORIZATION_CODE: ar.Authorized = true case osin.REFRESH_TOKEN: ar.Authorized = true case osin.PASSWORD: // if ar.Username == "test" && ar.Password == "test" { // ar.Authorized = true // ar.UserData = "1:1" // } else { userInfos, err := getUserInfos(ar.Username, ar.Password, r) if err != nil { resp.IsError = true resp.InternalError = err } else { ar.Authorized = true } ar.UserData = userInfos // } } server.FinishAccessRequest(resp, r, ar) } if resp.IsError && resp.InternalError != nil { logs.Error(resp.InternalError.Error()) Fail(w, r, map[string]interface{}{"user": resp.InternalError.Error()}, http.StatusBadRequest) return } osin.OutputJSON(resp, w, r) }
// CreateGroup calls the GroupSQL Save method and returns the results func CreateGroup(w http.ResponseWriter, r *http.Request) { var ( g = new(models.Group) err error ) if err = Request(&views.Group{Group: g}, r); err != nil { logs.Debug(err) Fail(w, r, map[string]interface{}{"group": err.Error()}, http.StatusBadRequest) return } var ( db = getDB(r) groupStore = models.GroupStore(db) ) if err = groupStore.Save(g); err != nil { logs.Error(err) Error(w, r, err.Error(), http.StatusInternalServerError) return } Success(w, r, views.Group{Group: g}, http.StatusCreated) }
func add(ctx *cli.Context) error { var err error var config settings.Config if ctx.String("config") != "" { config, err = settings.Parse(ctx.String("config")) if err != nil { logs.Error(err) } } var mail = ctx.String("mail") var password = ctx.String("password") var firstname = ctx.String("firstname") var surname = ctx.String("surname") var groupID = ctx.String("group") if mail == "" || password == "" || firstname == "" || surname == "" { logs.Error("All arguments are required") return errors.New("all arguments are required") } passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { panic(err) } var convGroupID = 0 if groupID != "" { convGroupID, err = strconv.Atoi(groupID) if err != nil { logs.Error(err) return err } } u := &models.User{ Mail: sPtr(mail), Password: sPtr(string(passwordHash)), Firstname: sPtr(firstname), Surname: sPtr(surname), GroupID: uint(convGroupID), } errs := u.Validate() logs.Level(logs.DebugLevel) if len(errs) > 0 { logs.Error(errs) return errors.New("Informations are not valid") } dialect, args, err := config.SqlDB() if err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("database type: %s", dialect) var db *gorm.DB if db, err = databases.InitGORM(dialect, args); err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("connected to %s", args) if config.Migrate() { db.AutoMigrate(models.Models()...) logs.Debug("database migrated successfully") } db.LogMode(true) var store = models.UserStore(db) err = store.Save(u) if err != nil { logs.Error(err) return err } logs.Debug("New user :"******"-Mail : %s", mail) logs.Debug("-Password : %s", password) logs.Debug("-Firstname : %s", firstname) logs.Debug("-Surname : %s", surname) logs.Debug("-GroupID : %d", convGroupID) return nil }
// CreateFacts receive a polygon and retrieves every contact in this polygon. It then calls the CreateFact method for each contact. func CreateFactsByShape(w http.ResponseWriter, r *http.Request) { var sourceArgs = &models.FactsJson{GroupID: router.Context(r).Env["GroupID"].(uint)} if err := Request(sourceArgs, r); err != nil { logs.Debug(err) Fail(w, r, map[string]interface{}{"sourceArgs": err.Error()}, http.StatusBadRequest) return } var ( contactClient = rpcClient(r, "ContactClient") args = models.SearchArgs{} reply = models.SearchReply{} ) args.Search = new(models.Search) args.Search.Polygon = sourceArgs.Points args.Search.Filter = sourceArgs.Filter err := contactClient.Call("Search.SearchIDViaGeoPolygon", args, &reply) if err != nil { logs.Error(err) Error(w, r, err.Error(), http.StatusInternalServerError) return } var ( replyFacts = models.FactReply{} factArgs = models.FactArgs{Fact: &models.Fact{GroupID: sourceArgs.GroupID}} ) DefaultFact := &models.Fact{} DefaultFact = &models.Fact{} DefaultFact.GroupID = sourceArgs.GroupID DefaultFact.Action.Name = sourceArgs.Name DefaultFact.Action.Pitch = sourceArgs.Pitch DefaultFact.Action.TypeData = sourceArgs.TypeData DefaultFact.Status = sourceArgs.Status if reply.IDs != nil { for _, ID := range reply.IDs { factArgs.Fact = DefaultFact factArgs.Fact.ContactID = ID err := contactClient.Call("Fact.Create", factArgs, &replyFacts) if err != nil { Error(w, r, err.Error(), http.StatusInternalServerError) return } if replyFacts.Fact.Contact.ID == 0 { logs.Debug("Contact %d didn't exist. Fact %d may therefore be incorrect", ID, replyFacts.Fact.ID) } factArgs.Fact = replyFacts.Fact err = contactClient.Call("Search.IndexFact", factArgs, &replyFacts) if err != nil { Error(w, r, err.Error(), http.StatusInternalServerError) return } logs.Debug("Fact %d created and indexed", replyFacts.Fact.ID) replyFacts.Facts = append(replyFacts.Facts, *replyFacts.Fact) } } Success(w, r, views.Facts{Facts: replyFacts.Facts}, http.StatusOK) }
func serve(ctx *cli.Context) error { var err error var config settings.Config if ctx.String("config") != "" { config, err = settings.Parse(ctx.String("config")) if err != nil { logs.Error(err) } } if config.Debug() { logs.Level(logs.DebugLevel) } dialect, args, err := config.SqlDB() if err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("database type: %s", dialect) var app = application.New() if app.Components["DB"], err = databases.InitGORM(dialect, args); err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("connected to %s", args) if config.Migrate() { app.Components["DB"].(*gorm.DB).AutoMigrate(models.Models()...) logs.Debug("database migrated successfully") } redisSettings, err := config.Redis() client := redis.NewClient(&redis.Options{Addr: redisSettings.String()}) if _, err := client.Ping().Result(); err != nil { return err } logs.Debug("Connected to Redis at %s", redisSettings.String()) app.Components["Redis"] = client cfg := osin.NewServerConfig() cfg.AllowedAuthorizeTypes = osin.AllowedAuthorizeType{osin.CODE, osin.TOKEN} cfg.AllowedAccessTypes = osin.AllowedAccessType{osin.AUTHORIZATION_CODE, osin.REFRESH_TOKEN, osin.PASSWORD} oauthServer := osin.NewServer(cfg, components.NewRedisStorage(client)) app.Components["OAuth"] = oauthServer app.Components["Templates"] = views.Templates() app.Components["Mux"] = gojimux.New() if config.Debug() { app.Components["DB"].(*gorm.DB).LogMode(true) app.Use(router.Logger) } app.Use(app.Apply) app.Get("/oauth2/authorize", controllers.Authorize) app.Post("/oauth2/token", controllers.Token) app.Get("/oauth2/info", controllers.Info) app.Post("/users/register", controllers.Register) app.Get("/users/:id", controllers.RetrieveUser) app.Get("/groups", controllers.RetrieveGroupCollection) app.Post("/groups", controllers.CreateGroup) app.Get("/groups/:id", controllers.RetrieveGroup) app.Delete("/groups/:id", controllers.DeleteGroup) app.Patch("/groups/:id", controllers.UpdateGroup) server, err := config.Server() if err != nil { logs.Critical(err) os.Exit(1) } return app.Serve(server.String()) }
func script(ctx *cli.Context) error { var err error var config settings.Config if ctx.String("config") != "" { config, err = settings.Parse(ctx.String("config")) if err != nil { logs.Error(err) } } logs.Level(logs.DebugLevel) dialect, args, err := config.SqlDB() if err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("database type: %s", dialect) var db *gorm.DB if db, err = databases.InitGORM(dialect, args); err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("connected to %s", args) if config.Migrate() { db.AutoMigrate(models.Models()...) logs.Debug("database migrated successfully") } db.LogMode(true) ElasticSettings, err := config.Elasticsearch() var client *elastic.Client client, err = dialElasticRetry(ElasticSettings.String()) if err != nil { logs.Critical(err) os.Exit(1) } // Use the IndexExists service to check if a specified index exists. exists, err := client.IndexExists("contacts").Do() if err != nil { logs.Critical(err) os.Exit(1) } if !exists { logs.Critical("No contacts index") os.Exit(1) } ID, err := findID(client) if err != nil { logs.Debug(err) os.Exit(1) } logs.Debug("Last ID is : %d", ID) contacts, err := findContacts(ID, db) for _, contact := range contacts { contact, err := addAddresses(contact, db) if err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("Indexing contact %d : %s %s", contact.ID, contact.Surname, contact.Firstname) err = index(contact, client) if err != nil { logs.Critical(err) os.Exit(1) } } return nil }
func serve(ctx *cli.Context) error { clientID := ctx.String("client-id") clientSecret := ctx.String("client-secret") var config settings.Config var err error if ctx.String("config") != "" { config, err = settings.Parse(ctx.String("config")) if err != nil { logs.Error(err) } } if config.Debug() { logs.Level(logs.DebugLevel) } redisSettings, err := config.Redis() client := redis.NewClient(&redis.Options{Addr: redisSettings.String()}) if _, err := client.Ping().Result(); err != nil { return err } logs.Debug("Connected to Redis at %s", redisSettings.String()) store := components.NewRedisStore(client) proxy := goproxy.NewProxyHttpServer() if config.Debug() { proxy.Verbose = true } // Treat only requests with an SID cookie or POSTing username and password. var session = goproxy.ReqConditionFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) bool { _, err := req.Cookie("SID") return err == nil || (req.Method == "POST" && req.FormValue("username") != "" && req.FormValue("password") != "") // The form is already parsed. }) proxy.NonproxyHandler = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { dump, _ := httputil.DumpRequest(req, true) fmt.Println(string(dump)) req.URL.Scheme = req.Header.Get("X-Scheme") req.URL.Host = req.Host proxy.ServeHTTP(w, req) }) proxy.OnRequest(session).DoFunc( func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { //dump, _ := httputil.DumpRequest(req, true) //fmt.Println(string(dump)) cookie, err := req.Cookie("SID") if err == nil { session, err := store.Load(cookie.Value) if err != nil { return req, goproxy.NewResponse(req, "text/plain", http.StatusForbidden, "Invalid cookie") } req.Header.Del("Cookie") req.Header.Add("Authorization", "Bearer "+session.AccessToken) return req, nil } // Perform an OAuth "Resource Owner Password Credentials Grant" req.Form.Add("grant_type", "password") req.SetBasicAuth(clientID, clientSecret) // We must update the body and the content size for our new post value. var buffer io.Reader = strings.NewReader(req.Form.Encode()) req.Body = ioutil.NopCloser(buffer) switch v := buffer.(type) { case *bytes.Buffer: req.ContentLength = int64(v.Len()) case *bytes.Reader: req.ContentLength = int64(v.Len()) case *strings.Reader: req.ContentLength = int64(v.Len()) } //req.RequestURI = "" // Must be removed for client requests client := &http.Client{} resp, err := client.Do(req) if err != nil { return req, nil } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return req, nil } // TODO: Check http status for errors access := new(components.AccessData) if err := json.Unmarshal(body, access); err != nil { return req, nil } session := &components.Session{ ID: strings.TrimRight(base64.StdEncoding.EncodeToString(uuid.NewRandom()), "="), AccessToken: access.AccessToken, RefreshToken: access.RefreshToken, ExpiresIn: access.ExpiresIn, } if err := store.Save(session); err != nil { return req, nil } // TODO: Give a json response to clients resp = goproxy.NewResponse(req, "text/plain", http.StatusOK, "") cookie = &http.Cookie{Name: "SID", Value: session.ID} resp.Header.Add("Set-Cookie", cookie.String()) return req, resp }, ) server, err := config.Server() if err != nil { logs.Critical(err) os.Exit(1) } logs.Info("Listening on %s", server.String()) return http.ListenAndServe(server.String(), proxy) }
// Implementation of elasticsearch, gets the query terms from the request's url and calls the SearchContacts method from Contacts via RPC (Search client). Returns results via jsonapi. func SearchContact(w http.ResponseWriter, r *http.Request) { var ( contactClient = rpcClient(r, "ContactClient") args = models.SearchArgs{} reply = models.SearchReply{} ) args.Search = new(models.Search) //args.Search.Query = router.Context(r).Param("query") if err := Request(args.Search, r); err != nil { logs.Debug(err) Fail(w, r, map[string]interface{}{"contact": err.Error()}, http.StatusBadRequest) return } // choix de la fonction selon le type de recherche souhaité var filtre = "" if args.Search.Fields[1] == "address" { // recherche sur les addresses filtre = "Search.SearchAddressesAggs" } else if args.Search.Fields[1] == "geoloc" { // recherche par geoloc avec tri par distance filtre = "Search.SearchContactsGeoloc" } else { // recherche sur les contacts filtre = "Search.SearchContacts" } // appel des fonctions err := contactClient.Call(filtre, args, &reply) if err != nil { logs.Error(err) Error(w, r, err.Error(), http.StatusInternalServerError) return } // traitement des résultats selon le type de recherche -------------------------------------------- if args.Search.Fields[1] == "address" { if reply.AddressAggs == nil { reply.AddressAggs = make([]models.AddressAggReply, 0) } Success(w, r, views.AddressAggs{AddressAggs: reply.AddressAggs}, http.StatusOK) } else if args.Search.Fields[1] == "geoloc" { if reply.Contacts == nil { reply.Contacts = make([]models.Contact, 0) } var cs models.AddressAggReply var temp_contact models.Contact var compteur int = 0 var size_nb_address_aggrege int if len(args.Search.Fields) == 3 { j, err := strconv.Atoi(args.Search.Fields[2]) if err == nil { size_nb_address_aggrege = j } else { // par défaut size_nb_address_aggrege = 50 } } else { // par défaut size_nb_address_aggrege = 50 } for pos, res_contact := range reply.Contacts { //control si nous avons le nombre de fiche résultats suffisants: if compteur == size_nb_address_aggrege { break } // si il y'a égalité if temp_contact.Address.Location == res_contact.Address.Location { //égalité cs.Contacts = append(cs.Contacts, res_contact) //si il n'y a pas d'égalité } else { //pas d'égalité if pos == 0 { //première itération cs.Contacts = append(cs.Contacts, res_contact) } else { //pas la première itération reply.AddressAggs = append(reply.AddressAggs, cs) compteur = compteur + 1 // init de cs var cs2 models.AddressAggReply cs = cs2 cs.Contacts = append(cs.Contacts, res_contact) } } temp_contact = res_contact } reply.AddressAggs = append(reply.AddressAggs, cs) Success(w, r, views.AddressAggs{AddressAggs: reply.AddressAggs}, http.StatusOK) } else { // pas geoloc, pas address if reply.Contacts == nil { reply.Contacts = make([]models.Contact, 0) } Success(w, r, views.Contacts{Contacts: reply.Contacts}, http.StatusOK) } }
func script(ctx *cli.Context) error { var err error var config settings.Config if ctx.String("config") != "" { config, err = settings.Parse(ctx.String("config")) if err != nil { logs.Error(err) } } logs.Level(logs.DebugLevel) dialect, args, err := config.SqlDB() if err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("database type: %s", dialect) var db *gorm.DB if db, err = databases.InitGORM(dialect, args); err != nil { logs.Critical(err) os.Exit(1) } logs.Debug("connected to %s", args) if config.Migrate() { db.AutoMigrate(models.Models()...) logs.Debug("database migrated successfully") } db.LogMode(true) ElasticSettings, err := config.Elasticsearch() var client *elastic.Client client, err = dialElasticRetry(ElasticSettings.String()) if err != nil { logs.Critical(err) os.Exit(1) } // Use the IndexExists service to check if a specified index exists. exists, err := client.IndexExists("contacts").Do() if err != nil { logs.Critical(err) os.Exit(1) } if !exists { logs.Critical("No contacts index") os.Exit(1) } ID := config.Int("id") if ID == -1 { logs.Debug("Looking for ID") ID, err = findID(client) if err != nil { logs.Debug(err) os.Exit(1) } } logs.Debug("Last ID is : %d", ID) contacts, err := findContacts(ID, db) doContacts := config.Bool("contacts") doFacts := config.Bool("facts") if doContacts == false && doFacts == false { logs.Debug("Nothing to be done, please activate some options") os.Exit(1) } for _, contact := range contacts { id := contact.ID if id != 0 { contact, err := addAddresses(contact, db) if err == nil { if contact != nil { if doContacts { logs.Debug("Indexing contact %d : %s %s", id, contact.Surname, contact.Firstname) err = index(contact, client) if err != nil { logs.Critical(err) } } if doFacts { logs.Debug("Creating and indexing fact for contact %d : %s %s", id, contact.Surname, contact.Firstname) err = createFact(contact, client, db) if err != nil { logs.Critical(err) } } } else { logs.Debug("Could not index contact %d", id) } } } } return nil }