diff --git a/.gitignore b/.gitignore index ab3b38e..e2f7237 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ # env .env + +# .swp +*.swp diff --git a/v4/cmd/server.go b/v4/cmd/api.go similarity index 59% rename from v4/cmd/server.go rename to v4/cmd/api.go index 411eb13..a800734 100644 --- a/v4/cmd/server.go +++ b/v4/cmd/api.go @@ -18,11 +18,22 @@ var ( apiKey string ) -// serverCmd represents the server command -var serverCmd = &cobra.Command{ - Use: "server", +// 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") + + connection := data.PostgresConnection{ + User: viper.GetString("db.user"), + Password: viper.GetString("db.password"), + Host: viper.GetString("db.host"), + Database: viper.GetString("db.database"), + Port: viper.GetInt("db.port"), + } e := echo.New() @@ -52,14 +63,6 @@ var serverCmd = &cobra.Command{ // Execution - connection := data.PostgresConnection{ - User: viper.GetString("db.user"), - Password: viper.GetString("db.password"), - Host: viper.GetString("db.host"), - Database: viper.GetString("db.database"), - Port: viper.GetInt("db.port"), - } - client, err := data.NewDataClient(connection) if err != nil { log.Fatalf("Could not establish database connection.\n Error: %s\n", err) @@ -72,40 +75,45 @@ var serverCmd = &cobra.Command{ client.DB.Close() + log.Println("apiPort: ", apiPort) + log.Println("apiKey: ", apiKey) + e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", apiPort))) }, } func init() { - rootCmd.AddCommand(serverCmd) + rootCmd.AddCommand(apiCmd) // api.key - serverCmd.Flags().StringVar( - &apiKey, "api-key", "bottin", + apiCmd.Flags().String( + "api-key", "bottin", "API server key. Leave empty for no key auth. (config: 'api.key')") + viper.BindPFlag("api.key", apiCmd.Flags().Lookup("api-key")) // api.port - serverCmd.Flags().IntVar( - &apiPort, "api-port", 1312, + apiCmd.Flags().Int( + "api-port", 1312, "API server port (config:'api.port')") + viper.BindPFlag("api.port", apiCmd.Flags().Lookup("api-port")) // db.database - serverCmd.Flags().String("db-database", "bottin", "Postgres database (config:'db.database')") - viper.BindPFlag("db.database", serverCmd.Flags().Lookup("db-database")) + apiCmd.Flags().String("db-database", "bottin", "Postgres database (config:'db.database')") + viper.BindPFlag("db.database", apiCmd.Flags().Lookup("db-database")) // db.host - serverCmd.Flags().String("db-host", "postgres", "Postgres host (config:'db.host')") - viper.BindPFlag("db.host", serverCmd.Flags().Lookup("db-host")) + apiCmd.Flags().String("db-host", "db", "Postgres host (config:'db.host')") + viper.BindPFlag("db.host", apiCmd.Flags().Lookup("db-host")) // db.password - serverCmd.Flags().String("db-password", "bottin", "Postgres password (config:'db.password')") - viper.BindPFlag("db.password", serverCmd.Flags().Lookup("db-password")) + apiCmd.Flags().String("db-password", "bottin", "Postgres password (config:'db.password')") + viper.BindPFlag("db.password", apiCmd.Flags().Lookup("db-password")) // db.port - serverCmd.Flags().Int("db-port", 5432, "Postgres port (config:'db.port')") - viper.BindPFlag("db.port", serverCmd.Flags().Lookup("db-port")) + apiCmd.Flags().Int("db-port", 5432, "Postgres port (config:'db.port')") + viper.BindPFlag("db.port", apiCmd.Flags().Lookup("db-port")) // db.user - serverCmd.Flags().String("db-user", "bottin", "Postgres user (config:'db.user')") - viper.BindPFlag("db.user", serverCmd.Flags().Lookup("db-user")) + apiCmd.Flags().String("db-user", "bottin", "Postgres user (config:'db.user')") + viper.BindPFlag("db.user", apiCmd.Flags().Lookup("db-user")) } diff --git a/v4/cmd/web.go b/v4/cmd/web.go index ab10ba0..6e812f7 100644 --- a/v4/cmd/web.go +++ b/v4/cmd/web.go @@ -1,20 +1,129 @@ package cmd import ( + "crypto/subtle" + "embed" "fmt" + "html/template" + "io" + "log" + "git.agecem.com/agecem/bottin/v4/web" + "git.agecem.com/agecem/bottin/v4/web/webhandlers" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" "github.com/spf13/cobra" + "github.com/spf13/viper" ) +var ( + webUser string + webPassword string + webPort int + webApiHost string + webApiKey string + webApiPort int +) + +var templatesFS embed.FS + +type Template struct { + templates *template.Template +} + +func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error { + return t.templates.ExecuteTemplate(w, name, data) +} + // webCmd represents the web command var webCmd = &cobra.Command{ Use: "web", Short: "Démarrer le client web", + Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { - fmt.Println("web called") + webApiHost = viper.GetString("web.api.host") + webApiKey = viper.GetString("web.api.key") + webApiPort = viper.GetInt("web.api.port") + webPassword = viper.GetString("web.password") + webPort = viper.GetInt("web.port") + webUser = viper.GetString("web.user") + + e := echo.New() + + // Middlewares + + e.Pre(middleware.AddTrailingSlash()) + + e.Use(middleware.BasicAuth(func(user, password string, c echo.Context) (bool, error) { + usersMatch := subtle.ConstantTimeCompare([]byte(user), []byte(webUser)) == 1 + passwordsMatch := subtle.ConstantTimeCompare([]byte(password), []byte(webPassword)) == 1 + return usersMatch && passwordsMatch, nil + })) + + // Template + + t := &Template{ + templates: template.Must(template.ParseFS(templatesFS, "templates/*.html")), + } + + e.Renderer = t + + // Routes + + e.GET("/", webhandlers.GetIndex) + + // Execution + + fmt.Println("webPort: ", webPort) + fmt.Println("web.port: ", viper.GetInt("web.port")) + webPortFlag, err := cmd.Flags().GetInt("web-port") + if err != nil { + log.Fatal(err) + } + fmt.Println("web-port: ", webPortFlag) + + e.Logger.Fatal(e.Start( + fmt.Sprintf(":%d", webPort))) }, } func init() { rootCmd.AddCommand(webCmd) + templatesFS = web.GetTemplates() + + // web.api.host + webCmd.Flags().String( + "web-api-host", "api", + "Remote API server host (config:'web.api.host')") + viper.BindPFlag("web.api.host", webCmd.Flags().Lookup("web-api-host")) + + // web.api.key + webCmd.Flags().String( + "web-api-key", "bottin", + "Remote API server key (config:'web.api.key')") + viper.BindPFlag("web.api.key", webCmd.Flags().Lookup("web-api-key")) + + // web.api.port + webCmd.Flags().Int( + "web-api-port", 1312, + "Remote API server port (config:'web.api.port')") + viper.BindPFlag("web.api.port", webCmd.Flags().Lookup("web-api-port")) + + // web.password + webCmd.Flags().String( + "web-password", "bottin", + "Web client password (config:'web.password')") + viper.BindPFlag("web.password", webCmd.Flags().Lookup("web-password")) + + // web.port + webCmd.Flags().Int( + "web-port", 2312, + "Web client port (config:'web.port')") + viper.BindPFlag("web.port", webCmd.Flags().Lookup("web-port")) + + // web.user + webCmd.Flags().String( + "web-user", "bottin", + "Web client user (config:'web.user')") + viper.BindPFlag("web.user", webCmd.Flags().Lookup("web-user")) } diff --git a/v4/docker-compose.yaml b/v4/docker-compose.yaml index bfb46f1..53b726c 100644 --- a/v4/docker-compose.yaml +++ b/v4/docker-compose.yaml @@ -1,6 +1,6 @@ services: - postgres: + db: image: postgres:latest environment: POSTGRES_DATABASE: "${BOTTIN_POSTGRES_DATABASE}" @@ -11,11 +11,19 @@ services: volumes: - 'pgdata:/var/lib/postgresql/data' + #api: + # depends_on: db + + #web: + # depends_on: api + adminer: image: adminer restart: always ports: - 8088:8080 + depends_on: + - db volumes: pgdata: diff --git a/v4/web/embed.go b/v4/web/embed.go index cae74d2..465e5ec 100644 --- a/v4/web/embed.go +++ b/v4/web/embed.go @@ -2,9 +2,9 @@ package web import "embed" -//go:embed templates -var templates embed.FS +//go:embed templates/* +var templatesFS embed.FS func GetTemplates() embed.FS { - return templates + return templatesFS } diff --git a/v4/web/templates/index.html b/v4/web/templates/index.html index 7df8015..e318199 100644 --- a/v4/web/templates/index.html +++ b/v4/web/templates/index.html @@ -1 +1,31 @@ -Hello world from bottin +{{ define "index-html" }} + + + + + + AGECEM | Bottin + + + + +

+ Bottin des membres de l'AGECEM +

+ +

+ Scannez la carte étudiante d'unE membre
+ -ou-
+ Entrez manuellement le code à 7 chiffres +

+ +
+ + +
+ + + +{{ end }} diff --git a/v4/web/webhandlers/handlers.go b/v4/web/webhandlers/handlers.go new file mode 100644 index 0000000..8376dd8 --- /dev/null +++ b/v4/web/webhandlers/handlers.go @@ -0,0 +1,11 @@ +package webhandlers + +import ( + "net/http" + + "github.com/labstack/echo/v4" +) + +func GetIndex(c echo.Context) error { + return c.Render(http.StatusOK, "index-html", nil) +}