...
1 package verify
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "io"
8 "net/http"
9 "time"
10
11 "edge-infra.dev/pkg/edge/iam/log"
12
13 "github.com/coreos/go-oidc/v3/oidc"
14 "github.com/gin-gonic/gin"
15 "golang.org/x/oauth2"
16 )
17
18 type LoginOptions struct {
19 SignInOnly bool `json:"sign_in_only" binding:"required"`
20 DisableScanBarcode bool `json:"disable_scan_barcode"`
21 Title string `json:"title"`
22 Message string `json:"message"`
23 Subject string `json:"subject"`
24 ErrorMessage string `json:"error_message"`
25 }
26
27 func (v *Verifier) startWithOptions(ctx *gin.Context) {
28 log := log.Get(ctx.Request.Context())
29
30 var uxSettings LoginOptions
31
32 uxSettings.Title = ctx.Request.FormValue("Title")
33 uxSettings.Message = ctx.Request.FormValue("Message")
34 uxSettings.Subject = ctx.Request.FormValue("Subject")
35 uxSettings.ErrorMessage = ctx.Request.FormValue("ErrorMessage")
36 Signin := false
37 if ctx.Request.FormValue("SignInOnly") == "on" {
38 Signin = true
39 }
40 uxSettings.SignInOnly = Signin
41 DisableScanBarcode := false
42 if ctx.Request.FormValue("DisableScanBarcode") == "on" {
43 DisableScanBarcode = true
44 }
45 uxSettings.DisableScanBarcode = DisableScanBarcode
46
47 loginHint, err := v.requestForUXSettings(uxSettings)
48 if err != nil {
49 err := ctx.AbortWithError(http.StatusInternalServerError, err)
50 if err != nil {
51 log.Error(err, "failed to abort with error")
52 }
53 return
54 }
55
56 provider, err := oidc.NewProvider(oidc.InsecureIssuerURLContext(ctx, Issuer()), IssuerURL())
57 if err != nil {
58 err := ctx.AbortWithError(http.StatusInternalServerError, err)
59 if err != nil {
60 log.Error(err, "failed to abort with error")
61 }
62 return
63 }
64
65 config := oauth2.Config{
66 ClientID: v.ClientID,
67 ClientSecret: v.ClientSecret,
68 RedirectURL: v.ClientURL + verifyCallbackPath,
69 Endpoint: provider.Endpoint(),
70 Scopes: []string{oidc.ScopeOpenID, oidc.ScopeOfflineAccess, "profile"},
71 }
72
73 authCodeURL := config.AuthCodeURL("332b7b6ue34ds", oauth2.SetAuthURLParam("login_hint", loginHint))
74
75 ctx.Redirect(http.StatusFound, authCodeURL)
76 }
77
78 func (v *Verifier) requestForUXSettings(clientCustomFields LoginOptions) (string, error) {
79 var loginHint string
80 b, err := json.Marshal(clientCustomFields)
81 if err != nil {
82 return loginHint, err
83 }
84
85 req, err := http.NewRequest(http.MethodPost, IssuerURL()+"/oauth2/setup-auth", bytes.NewBuffer(b))
86 if err != nil {
87 return loginHint, err
88 }
89
90
91 req.Header.Add("Accept", gin.MIMEPlain)
92 req.Header.Add("Content-Type", gin.MIMEJSON)
93 req.SetBasicAuth(v.ClientID, v.ClientSecret)
94
95 client := &http.Client{Timeout: 5 * time.Minute}
96 res, err := client.Do(req)
97 if err != nil {
98 return loginHint, err
99 }
100 defer res.Body.Close()
101
102
103 gotStatusCode := res.StatusCode
104 expectedStatusCode := http.StatusCreated
105 if gotStatusCode != expectedStatusCode {
106 return loginHint, fmt.Errorf("request failed: expected: %d but got %d", expectedStatusCode, gotStatusCode)
107 }
108
109 respBody, err := io.ReadAll(res.Body)
110 if err != nil {
111 return loginHint, err
112 }
113 return (string(respBody)), nil
114 }
115
View as plain text