github.com/linchen2chris/hugo@v0.0.0-20230307053224-cec209389705/config/security/whitelist.go (about) 1 // Copyright 2021 The Hugo Authors. All rights reserved. 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 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package security 15 16 import ( 17 "encoding/json" 18 "fmt" 19 "regexp" 20 "strings" 21 ) 22 23 const ( 24 acceptNoneKeyword = "none" 25 ) 26 27 // Whitelist holds a whitelist. 28 type Whitelist struct { 29 acceptNone bool 30 patterns []*regexp.Regexp 31 32 // Store this for debugging/error reporting 33 patternsStrings []string 34 } 35 36 // MarshalJSON is for internal use only. 37 func (w Whitelist) MarshalJSON() ([]byte, error) { 38 if w.acceptNone { 39 return json.Marshal(acceptNoneKeyword) 40 } 41 42 return json.Marshal(w.patternsStrings) 43 } 44 45 // NewWhitelist creates a new Whitelist from zero or more patterns. 46 // An empty patterns list or a pattern with the value 'none' will create 47 // a whitelist that will Accept none. 48 func NewWhitelist(patterns ...string) Whitelist { 49 if len(patterns) == 0 { 50 return Whitelist{acceptNone: true} 51 } 52 53 var acceptSome bool 54 var patternsStrings []string 55 56 for _, p := range patterns { 57 if p == acceptNoneKeyword { 58 acceptSome = false 59 break 60 } 61 62 if ps := strings.TrimSpace(p); ps != "" { 63 acceptSome = true 64 patternsStrings = append(patternsStrings, ps) 65 } 66 } 67 68 if !acceptSome { 69 return Whitelist{ 70 acceptNone: true, 71 } 72 } 73 74 var patternsr []*regexp.Regexp 75 76 for i := 0; i < len(patterns); i++ { 77 p := strings.TrimSpace(patterns[i]) 78 if p == "" { 79 continue 80 } 81 patternsr = append(patternsr, regexp.MustCompile(p)) 82 } 83 84 return Whitelist{patterns: patternsr, patternsStrings: patternsStrings} 85 } 86 87 // Accepted reports whether name is whitelisted. 88 func (w Whitelist) Accept(name string) bool { 89 if w.acceptNone { 90 return false 91 } 92 93 for _, p := range w.patterns { 94 if p.MatchString(name) { 95 return true 96 } 97 } 98 return false 99 } 100 101 func (w Whitelist) String() string { 102 return fmt.Sprint(w.patternsStrings) 103 }