github.com/greenpau/go-authcrunch@v1.0.50/pkg/authz/bypass/bypass.go (about) 1 // Copyright 2022 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 bypass 16 17 import ( 18 "fmt" 19 "net/http" 20 "regexp" 21 "strings" 22 ) 23 24 type bypassMatchStrategy int 25 26 const ( 27 bypassMatchUnknown bypassMatchStrategy = 0 28 bypassMatchExact bypassMatchStrategy = 1 29 bypassMatchPartial bypassMatchStrategy = 2 30 bypassMatchPrefix bypassMatchStrategy = 3 31 bypassMatchSuffix bypassMatchStrategy = 4 32 bypassMatchRegex bypassMatchStrategy = 5 33 ) 34 35 // Config contains the entry for the authorization bypass. 36 type Config struct { 37 MatchType string `json:"match_type,omitempty" xml:"match_type,omitempty" yaml:"match_type,omitempty"` 38 URI string `json:"uri,omitempty" xml:"uri,omitempty" yaml:"uri,omitempty"` 39 match bypassMatchStrategy 40 regex *regexp.Regexp 41 } 42 43 // Validate validates Config 44 func (b *Config) Validate() error { 45 switch b.MatchType { 46 case "exact": 47 b.match = bypassMatchExact 48 case "partial": 49 b.match = bypassMatchPartial 50 case "prefix": 51 b.match = bypassMatchPrefix 52 case "suffix": 53 b.match = bypassMatchSuffix 54 case "regex": 55 b.match = bypassMatchRegex 56 case "": 57 return fmt.Errorf("undefined bypass match type") 58 default: 59 return fmt.Errorf("invalid %q bypass match type", b.MatchType) 60 } 61 b.URI = strings.TrimSpace(b.URI) 62 if b.URI == "" { 63 return fmt.Errorf("undefined bypass uri") 64 } 65 if b.regex == nil { 66 r, err := regexp.Compile(b.URI) 67 if err != nil { 68 return err 69 } 70 b.regex = r 71 } 72 return nil 73 } 74 75 // Match matches HTTP URL to the bypass configuration. 76 func Match(r *http.Request, cfgs []*Config) bool { 77 for _, cfg := range cfgs { 78 switch cfg.match { 79 case bypassMatchExact: 80 if cfg.URI == r.URL.Path { 81 return true 82 } 83 case bypassMatchPartial: 84 if strings.Contains(r.URL.Path, cfg.URI) { 85 return true 86 } 87 case bypassMatchPrefix: 88 if strings.HasPrefix(r.URL.Path, cfg.URI) { 89 return true 90 } 91 case bypassMatchSuffix: 92 if strings.HasSuffix(r.URL.Path, cfg.URI) { 93 return true 94 } 95 case bypassMatchRegex: 96 if cfg.regex.MatchString(r.URL.Path) { 97 return true 98 } 99 } 100 } 101 return false 102 }