github.com/anakojm/hugo-katex@v0.0.0-20231023141351-42d6f5de9c0b/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, error) { 49 if len(patterns) == 0 { 50 return Whitelist{acceptNone: true}, nil 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 }, nil 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 re, err := regexp.Compile(p) 82 if err != nil { 83 return Whitelist{}, fmt.Errorf("failed to compile whitelist pattern %q: %w", p, err) 84 } 85 patternsr = append(patternsr, re) 86 } 87 88 return Whitelist{patterns: patternsr, patternsStrings: patternsStrings}, nil 89 } 90 91 // MustNewWhitelist creates a new Whitelist from zero or more patterns and panics on error. 92 func MustNewWhitelist(patterns ...string) Whitelist { 93 w, err := NewWhitelist(patterns...) 94 if err != nil { 95 panic(err) 96 } 97 return w 98 } 99 100 // Accept reports whether name is whitelisted. 101 func (w Whitelist) Accept(name string) bool { 102 if w.acceptNone { 103 return false 104 } 105 106 for _, p := range w.patterns { 107 if p.MatchString(name) { 108 return true 109 } 110 } 111 return false 112 } 113 114 func (w Whitelist) String() string { 115 return fmt.Sprint(w.patternsStrings) 116 }