AuthStateHandler /auth/{state}/ - validate info from oauth provider (Google, GitHub, OIDC, etc) - issue jwt in the form of a cookie
(w http.ResponseWriter, r *http.Request)
| 53 | // - validate info from oauth provider (Google, GitHub, OIDC, etc) |
| 54 | // - issue jwt in the form of a cookie |
| 55 | func AuthStateHandler(w http.ResponseWriter, r *http.Request) { |
| 56 | log.Debug("/auth/{state}/") |
| 57 | // Handle the exchange code to initiate a transport. |
| 58 | |
| 59 | session, err := sessstore.Get(r, cfg.Cfg.Session.Name) |
| 60 | if err != nil { |
| 61 | responses.Error400(w, r, fmt.Errorf("/auth %w: could not find session store %s", err, cfg.Cfg.Session.Name)) |
| 62 | return |
| 63 | } |
| 64 | |
| 65 | // is the nonce "state" valid? |
| 66 | queryState := r.URL.Query().Get("state") |
| 67 | if session.Values["state"] != queryState { |
| 68 | responses.Error400(w, r, fmt.Errorf("/auth Invalid session state: stored %s, returned %s", session.Values["state"], queryState)) |
| 69 | return |
| 70 | } |
| 71 | |
| 72 | user := structs.User{} |
| 73 | customClaims := structs.CustomClaims{} |
| 74 | ptokens := structs.PTokens{} |
| 75 | |
| 76 | // is code challenge enabled? |
| 77 | authCodeOptions := []oauth2.AuthCodeOption{} |
| 78 | |
| 79 | if cfg.GenOAuth.CodeChallengeMethod != "" { |
| 80 | authCodeOptions = []oauth2.AuthCodeOption{ |
| 81 | oauth2.SetAuthURLParam("code_challenge", session.Values["codeChallenge"].(string)), |
| 82 | oauth2.SetAuthURLParam("code_verifier", session.Values["codeVerifier"].(string)), |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | if err := getUserInfo(r, &user, &customClaims, &ptokens, authCodeOptions...); err != nil { |
| 87 | responses.Error400(w, r, fmt.Errorf("/auth Error while retrieving user info after successful login at the OAuth provider: %w", err)) |
| 88 | return |
| 89 | } |
| 90 | log.Debugf("/auth/{state}/ Claims from userinfo: %+v", customClaims) |
| 91 | |
| 92 | // verify / authz the user |
| 93 | if ok, err := verifyUser(user); !ok { |
| 94 | responses.Error403(w, r, fmt.Errorf("/auth User is not authorized: %w . Please try again or seek support from your administrator", err)) |
| 95 | return |
| 96 | } |
| 97 | |
| 98 | // SUCCESS!! they are authorized |
| 99 | |
| 100 | // issue the jwt |
| 101 | |
| 102 | tokenstring, err := jwtmanager.NewVPJWT(user, customClaims, ptokens) |
| 103 | if err != nil { |
| 104 | responses.Error500(w, r, fmt.Errorf("/auth Token creation failure: %w . Please seek support from your administrator", err)) |
| 105 | return |
| 106 | |
| 107 | } |
| 108 | cookie.SetCookie(w, r, tokenstring) |
| 109 | |
| 110 | // get the originally requested URL so we can send them on their way |
| 111 | requestedURL := session.Values["requestedURL"].(string) |
| 112 | if requestedURL != "" { |