package verify
import (
"bytes"
"html/template"
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-logr/logr"
"edge-infra.dev/pkg/edge/iam/middleware"
)
type BarcodeScanner struct {
ScanBarcodeURI string
Image string
Token string
}
type BarcodeResult struct {
FailureURI string
RedirectURI string
Image string
Token string
HTML template.HTML
}
type Result struct {
Name string
Steps []Step
Pass bool
Barcode BarcodeResult
}
type Step struct {
Name string
Description string
Pass bool
IsPublic bool
Expected string
Got string
}
type Verifier struct {
ClientID string
ClientSecret string
ClientURL string
}
func Serve(log logr.Logger) error {
// create and configure a new Gin router
router := gin.New()
router.Use(middleware.SetOperationInContext())
router.Use(middleware.IntoContext(log))
router.Use(middleware.RequestLogger(log))
// When in dev mode all calls are from outside and localhost:8080 will work. Hence we dont require the reverse proxy.
if !DevMode() {
//running reverse proxy
reverseproxy()
}
verifier := &Verifier{
ClientID: ClientID(),
ClientSecret: ClientSecret(),
ClientURL: ClientURL(),
}
// serve up our main capabilities
router.GET("", begin)
router.GET("/choose", choose)
router.GET("/custom", custom)
router.GET("/verify", verifier.start)
router.GET("/verify/customize", verifier.startWithOptions)
router.GET("/verify/client", verifier.client)
router.GET("/verify/print-barcode", verifier.printBarcode)
router.GET(verifyCallbackPath, verifier.callback)
router.GET("/verify/view-barcode", verifier.viewBarcode)
router.GET("/verify/scan-barcode", verifier.scanBarcode)
router.GET("/live", func(c *gin.Context) { c.Status(http.StatusOK) })
router.GET("/ready", func(c *gin.Context) {
if isReady() {
c.Status(http.StatusOK)
} else {
c.Status(http.StatusServiceUnavailable)
}
})
log.Info("serving up verify-client...")
return router.Run(Addr())
}
func writeResult(ctx *gin.Context, tmpl string, result *Result, steps ...Step) {
result.Steps = append(result.Steps, steps...)
// mark result to be failed, if any of the steps did not pass
for _, step := range result.Steps {
if !step.Pass {
result.Pass = false
break
}
}
t, err := template.New("").Parse(tmpl)
tpl := template.Must(t, err)
var w bytes.Buffer
_ = tpl.Execute(&w, result)
ctx.Data(http.StatusOK, "text/html", w.Bytes())
}
func isReady() bool {
// check if provider is ready
res, err := http.Get(InClusterIssuerURL() + "/ready")
if err != nil {
return false
}
return res.StatusCode == http.StatusOK
}