package bottin import ( "crypto/subtle" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "git.agecem.com/agecem/bottin/data" "git.agecem.com/agecem/bottin/embed" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/spf13/viper" ) var ( login_username, login_password string server_port int db_host, db_user, db_password, db_name string db_port int db_type, db_path string json_insert_path string insert_batch_size int html string ) // Funcs func init() { html = embed.ReadHtml() } // JSON to []*data.Membre func obtenirUnmarshalJSON(path string) ([]*data.Membre, error) { content, err := ioutil.ReadFile(path) if err != nil { return nil, err } var membres_insert []*data.Membre err_json := json.Unmarshal([]byte(content), &membres_insert) if err_json != nil { return nil, err_json } return membres_insert, nil } func membreToJson(membre *data.Membre) ([]byte, error) { membreJson, err := json.Marshal(membre) return membreJson, err } // Import flags from viper func UpdateFlags() { db_type = viper.GetString("db.type") db_path = viper.GetString("db.sqlite.path") server_port = viper.GetInt("server.port") login_username = viper.GetString("login.username") login_password = viper.GetString("login.password") insert_batch_size = viper.GetInt("import.insert_batch_size") } // Batch insert par json passé par argument func InsertJson(json_insert_path string) { if json_insert_path != "" { log.Printf("Trying to import json: %s", json_insert_path) newMembres, err_insert := obtenirUnmarshalJSON(json_insert_path) if newMembres != nil { log.Printf("Membres found, importing...") data.InsertMembres(newMembres, insert_batch_size) log.Printf("Success?") } if err_insert != nil { log.Fatal(err_insert) } } } // Run echo webserver func RunServer() { // Echo instance and group e := echo.New() g := e.Group("") // Middlewares // Compatibilité e.Pre(middleware.Rewrite(map[string]string{ "/membre/?num_etud=*": "/membre/$1", })) e.Pre(middleware.RemoveTrailingSlash()) // Authentification de base g.Use(middleware.BasicAuth(basicAuther)) // Logger - Choose one // Verbose logger //g.Use(middleware.Logger()) // Less verbose logger g.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ Format: "${time_rfc3339_nano} method=${method}, uri=${uri}, status=${status}" + "\n", })) // Routes registerRoutes(g) registerRoutesv1(g) // Start server e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", server_port))) } // Handlers func basicAuther(username, password string, context echo.Context) (bool, error) { if subtle.ConstantTimeCompare([]byte(username), []byte(login_username)) == 1 && subtle.ConstantTimeCompare([]byte(password), []byte(login_password)) == 1 { return true, nil } return false, nil } func registerRoutesv1(g *echo.Group) { g.GET("/v1", showAPISpecs) g.GET("/v1/membre/:num_etud", showMembreJson) } func showMembreJson(c echo.Context) error { num_etud := c.Param("num_etud") var membre data.Membre = data.ReadMembre(num_etud) return c.JSON(http.StatusOK, membre) } func showAPISpecs(c echo.Context) error { apispec := fmt.Sprintln(`agecem/bottin API Specifications ----- '/v1' | GET | Afficher spécifications API '/v1/membre/:num_etud' | GET | Afficher membre avec le numéro étudiant :num_etud, en JSON '/membre/:num_etud' | GET | Afficher membre avec le numéro étudiant :num_etud '/' | GET | Afficher bottin web '/membre' | GET | Afficher bottin web '/static' | GET | DEPRECATED Répertoire des fichiers statics -----`) return c.String(http.StatusOK, apispec) } func registerRoutes(g *echo.Group) { g.GET("/", func(c echo.Context) error { return c.HTML(http.StatusOK, html) }) // Doublon de l'autre le temps que j'figure out les shits g.GET("/membre", func(c echo.Context) error { return c.HTML(http.StatusOK, html) }) // Get specific membre g.GET("/membre/:num_etud", func(c echo.Context) error { num_etud := c.Param("num_etud") var membre data.Membre = data.ReadMembre(num_etud) msgNumEtud := fmt.Sprintf("

Numéro d'étudiantE: %s

", num_etud) msgNom := fmt.Sprintf("

Nom: %s

", membre.Nom) msg := fmt.Sprintf("%s%s%s", html, msgNumEtud, msgNom) return c.HTML(http.StatusOK, fmt.Sprintf(msg)) }) }