github.com/greenpau/go-authcrunch@v1.1.4/pkg/authn/api_test_user_uni_sec_factor_reg.go (about) 1 // Copyright 2024 Paul Greenberg greenpau@outlook.com 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package authn 16 17 import ( 18 "context" 19 "net/http" 20 21 "github.com/greenpau/go-authcrunch/pkg/identity" 22 "github.com/greenpau/go-authcrunch/pkg/ids" 23 "github.com/greenpau/go-authcrunch/pkg/requests" 24 "github.com/greenpau/go-authcrunch/pkg/user" 25 "go.uber.org/zap" 26 ) 27 28 // TestUserUniSecFactorReg verifies U2F authenticator. 29 func (p *Portal) TestUserUniSecFactorReg( 30 ctx context.Context, 31 w http.ResponseWriter, 32 r *http.Request, 33 rr *requests.Request, 34 parsedUser *user.User, 35 resp map[string]interface{}, 36 usr *user.User, 37 backend ids.IdentityStore, 38 bodyData map[string]interface{}) error { 39 40 rr.MfaToken.Type = "u2f" 41 42 // Validate inputs. 43 if v, exists := bodyData["webauthn_register"]; exists { 44 rr.WebAuthn.Register = v.(string) 45 } else { 46 resp["message"] = "Profile API did not find webauthn_register in the request payload" 47 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 48 } 49 if v, exists := bodyData["webauthn_challenge"]; exists { 50 rr.WebAuthn.Challenge = v.(string) 51 } else { 52 resp["message"] = "Profile API did not find webauthn_challenge in the request payload" 53 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 54 } 55 if v, exists := bodyData["webauthn_request"]; exists { 56 rr.WebAuthn.Request = v.(string) 57 } else { 58 resp["message"] = "Profile API did not find webauthn_request in the request payload" 59 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 60 } 61 62 token, err := identity.NewMfaToken(rr) 63 if err != nil { 64 resp["message"] = "Profile API received malformed U2F token in the request payload" 65 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 66 } 67 68 wr, err := token.WebAuthnRequest(rr.WebAuthn.Request) 69 if err != nil { 70 p.logger.Warn( 71 "u2f token validation failed", 72 zap.String("session_id", rr.Upstream.SessionID), 73 zap.String("request_id", rr.ID), 74 zap.Any("webauthn_request", wr), 75 zap.Any("error", err), 76 ) 77 resp["message"] = "Profile API failed to validate U2F token" 78 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 79 } 80 81 p.logger.Debug( 82 "Profile API successfully validated u2f token", 83 zap.String("session_id", rr.Upstream.SessionID), 84 zap.String("request_id", rr.ID), 85 zap.Any("webauthn_request", wr), 86 ) 87 88 respData := make(map[string]interface{}) 89 // TODO: replace with true 90 respData["success"] = true 91 resp["entry"] = respData 92 return handleAPIProfileResponse(w, rr, http.StatusOK, resp) 93 }