package verify import ( "bytes" "encoding/json" "fmt" "io" "net/http" "time" "edge-infra.dev/pkg/edge/iam/log" "github.com/coreos/go-oidc/v3/oidc" "github.com/gin-gonic/gin" "golang.org/x/oauth2" ) type LoginOptions struct { SignInOnly bool `json:"sign_in_only" binding:"required"` DisableScanBarcode bool `json:"disable_scan_barcode"` Title string `json:"title"` Message string `json:"message"` Subject string `json:"subject"` ErrorMessage string `json:"error_message"` } func (v *Verifier) startWithOptions(ctx *gin.Context) { log := log.Get(ctx.Request.Context()) var uxSettings LoginOptions uxSettings.Title = ctx.Request.FormValue("Title") uxSettings.Message = ctx.Request.FormValue("Message") uxSettings.Subject = ctx.Request.FormValue("Subject") uxSettings.ErrorMessage = ctx.Request.FormValue("ErrorMessage") Signin := false if ctx.Request.FormValue("SignInOnly") == "on" { Signin = true } uxSettings.SignInOnly = Signin DisableScanBarcode := false if ctx.Request.FormValue("DisableScanBarcode") == "on" { DisableScanBarcode = true } uxSettings.DisableScanBarcode = DisableScanBarcode loginHint, err := v.requestForUXSettings(uxSettings) if err != nil { err := ctx.AbortWithError(http.StatusInternalServerError, err) if err != nil { log.Error(err, "failed to abort with error") } return } provider, err := oidc.NewProvider(oidc.InsecureIssuerURLContext(ctx, Issuer()), IssuerURL()) if err != nil { err := ctx.AbortWithError(http.StatusInternalServerError, err) if err != nil { log.Error(err, "failed to abort with error") } return } config := oauth2.Config{ ClientID: v.ClientID, ClientSecret: v.ClientSecret, RedirectURL: v.ClientURL + verifyCallbackPath, Endpoint: provider.Endpoint(), Scopes: []string{oidc.ScopeOpenID, oidc.ScopeOfflineAccess, "profile"}, } authCodeURL := config.AuthCodeURL("332b7b6ue34ds", oauth2.SetAuthURLParam("login_hint", loginHint)) ctx.Redirect(http.StatusFound, authCodeURL) } func (v *Verifier) requestForUXSettings(clientCustomFields LoginOptions) (string, error) { var loginHint string b, err := json.Marshal(clientCustomFields) if err != nil { return loginHint, err } req, err := http.NewRequest(http.MethodPost, IssuerURL()+"/oauth2/setup-auth", bytes.NewBuffer(b)) if err != nil { return loginHint, err } // because there is a validation in the login endpoint req.Header.Add("Accept", gin.MIMEPlain) req.Header.Add("Content-Type", gin.MIMEJSON) req.SetBasicAuth(v.ClientID, v.ClientSecret) client := &http.Client{Timeout: 5 * time.Minute} res, err := client.Do(req) if err != nil { return loginHint, err } defer res.Body.Close() // make sure we are getting correct status code gotStatusCode := res.StatusCode expectedStatusCode := http.StatusCreated if gotStatusCode != expectedStatusCode { return loginHint, fmt.Errorf("request failed: expected: %d but got %d", expectedStatusCode, gotStatusCode) } respBody, err := io.ReadAll(res.Body) if err != nil { return loginHint, err } return (string(respBody)), nil }