package cmd import ( "crypto/subtle" "fmt" "log" "codeberg.org/vlbeaudoin/serpents" "git.agecem.com/agecem/bottin/v5/data" "git.agecem.com/agecem/bottin/v5/handlers" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/spf13/cobra" "github.com/spf13/viper" ) var ( apiPort int apiKey string ) // apiCmd represents the api command var apiCmd = &cobra.Command{ Use: "api", Short: "Démarrer le serveur API", Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { apiKey = viper.GetString("api.key") apiPort = viper.GetInt("api.port") e := echo.New() // Middlewares e.Pre(middleware.AddTrailingSlash()) if apiKey != "" { e.Use(middleware.KeyAuth(func(key string, c echo.Context) (bool, error) { return subtle.ConstantTimeCompare([]byte(key), []byte(apiKey)) == 1, nil })) } // DataClient client, err := data.NewDataClientFromViper() if err != nil { log.Fatalf("Could not establish database connection.\n Error: %s\n", err) } defer client.DB.Close() err = client.DB.Ping() if err != nil { log.Fatalf("Database was supposed to be ready but Ping() failed.\n Error: %s\n", err) } _, err = client.Seed() if err != nil { log.Fatalf("Error during client.Seed(): %s", err) } h := handlers.New(client) // Routes e.GET("/v5/health/", h.GetHealth) e.POST("/v5/membres/", h.PostMembres) e.GET("/v5/membres/", h.ListMembres) e.GET("/v5/membres/:membre_id/", h.ReadMembre) e.PUT("/v5/membres/:membre_id/prefered_name/", h.PutMembrePreferedName) e.POST("/v5/programmes/", h.PostProgrammes) e.POST("/v5/seed/", h.PostSeed) // Execution e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", apiPort))) }, } func init() { rootCmd.AddCommand(apiCmd) // api.key serpents.String(apiCmd.Flags(), "api.key", "api-key", "bottin", "API server key. Leave empty for no key auth") // api.port serpents.Int(apiCmd.Flags(), "api.port", "api-port", 1312, "API server port") // db.database serpents.String(apiCmd.Flags(), "db.database", "db-database", "bottin", "Postgres database") // db.host serpents.String(apiCmd.Flags(), "db.host", "db-host", "db", "Postgres host") // db.password serpents.String(apiCmd.Flags(), "db.password", "db-password", "bottin", "Postgres password") // db.port serpents.Int(apiCmd.Flags(), "db.port", "db-port", 5432, "Postgres port") // db.user serpents.String(apiCmd.Flags(), "db.user", "db-user", "bottin", "Postgres user") }