github.com/greenpau/go-authcrunch@v1.1.4/pkg/authn/api_test_user_ssh_key.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 "fmt" 20 "net/http" 21 "regexp" 22 23 "github.com/greenpau/go-authcrunch/pkg/identity" 24 "github.com/greenpau/go-authcrunch/pkg/ids" 25 "github.com/greenpau/go-authcrunch/pkg/requests" 26 "github.com/greenpau/go-authcrunch/pkg/user" 27 ) 28 29 var sshKeyRegexPattern1 = regexp.MustCompile(`^ssh-[a-z]+\s*[A-z0-9\+\/\=\n]+\s*`) 30 var sshKeyRegexPattern2 = regexp.MustCompile(`^[-]{3,5}\s*BEGIN\s[A-Z0-9]+\sPUBLIC\sKEY[-]{3,5}\s*`) 31 32 // TestUserSSHKey tests SSH key. 33 func (p *Portal) TestUserSSHKey( 34 ctx context.Context, 35 w http.ResponseWriter, 36 r *http.Request, 37 rr *requests.Request, 38 parsedUser *user.User, 39 resp map[string]interface{}, 40 usr *user.User, 41 backend ids.IdentityStore, 42 bodyData map[string]interface{}) error { 43 44 rr.Key.Usage = "ssh" 45 46 // Extract data. 47 if v, exists := bodyData["content"]; exists { 48 switch keyContent := v.(type) { 49 case string: 50 rr.Key.Payload = keyContent 51 default: 52 resp["message"] = "Profile API did find key content in the request payload, but it is malformed" 53 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 54 } 55 } else { 56 resp["message"] = "Profile API did not find key content in the request payload" 57 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 58 } 59 60 // Validate data. 61 if !sshKeyRegexPattern1.MatchString(rr.Key.Payload) && !sshKeyRegexPattern2.MatchString(rr.Key.Payload) { 62 resp["message"] = "Profile API found non-compliant SSH public key value" 63 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 64 } 65 66 pk, err := identity.NewPublicKey(rr) 67 if err != nil { 68 var errMsg string = fmt.Sprintf("the Profile API failed to convert input into SSH key: %v", err) 69 resp["message"] = errMsg 70 return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp) 71 } 72 73 respData := make(map[string]interface{}) 74 if pk != nil { 75 respData["success"] = true 76 if pk.FingerprintMD5 != "" { 77 respData["fingerprint_md5"] = pk.FingerprintMD5 78 } 79 if pk.Fingerprint != "" { 80 respData["fingerprint"] = pk.Fingerprint 81 } 82 if pk.Comment != "" { 83 respData["comment"] = pk.Comment 84 } 85 } else { 86 respData["success"] = false 87 } 88 resp["entry"] = respData 89 return handleAPIProfileResponse(w, rr, http.StatusOK, resp) 90 }