bottin/cmd/web.go

143 lines
3.2 KiB
Go

package cmd
import (
"crypto/subtle"
"embed"
"fmt"
"html/template"
"io"
"log"
"net/http"
"codeberg.org/vlbeaudoin/serpents"
"git.agecem.com/agecem/bottin/v5/data"
"git.agecem.com/agecem/bottin/v5/web"
"git.agecem.com/agecem/bottin/v5/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
webApiProtocol string
)
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) {
webApiHost = viper.GetString("web.api.host")
webApiKey = viper.GetString("web.api.key")
webApiPort = viper.GetInt("web.api.port")
webApiProtocol = viper.GetString("web.api.protocol")
webPassword = viper.GetString("web.password")
webPort = viper.GetInt("web.port")
webUser = viper.GetString("web.user")
// Ping API server
client := http.DefaultClient
defer client.CloseIdleConnections()
apiClient := data.NewApiClient(client, webApiKey, webApiHost, webApiProtocol, webApiPort)
pingResult, err := apiClient.GetHealth()
if err != nil {
log.Fatal(err)
}
log.Println(pingResult)
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
handler := webhandlers.Handler{APIClient: apiClient}
e.GET("/", handler.GetIndex)
e.GET("/membre/", handler.GetMembre)
// Execution
e.Logger.Fatal(e.Start(
fmt.Sprintf(":%d", webPort)))
},
}
func init() {
rootCmd.AddCommand(webCmd)
templatesFS = web.GetTemplates()
// web.api.host
serpents.String(webCmd.Flags(),
"web.api.host", "web-api-host", "api",
"Remote API server host")
// web.api.key
serpents.String(webCmd.Flags(),
"web.api.key", "web-api-key", "bottin",
"Remote API server key")
// web.api.protocol
serpents.String(webCmd.Flags(),
"web.api.protocol", "web-api-protocol", "http",
"Remote API server protocol")
// web.api.port
serpents.Int(webCmd.Flags(),
"web.api.port", "web-api-port", 1312,
"Remote API server port")
// web.password
serpents.String(webCmd.Flags(),
"web.password", "web-password", "bottin",
"Web client password")
// web.port
serpents.Int(webCmd.Flags(),
"web.port", "web-port", 2312,
"Web client port")
// web.user
serpents.String(webCmd.Flags(),
"web.user", "web-user", "bottin",
"Web client user")
}