11 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
14// UserMap holds information from the authenticated emails file
20// NewUserMap parses the authenticated emails file into a new UserMap
22// TODO (@NickMeves): Audit usage of `unsafe.Pointer` and potentially refactor
23func NewUserMap(usersFile string, done <-chan bool, onUpdate func()) *UserMap {
24 um := &UserMap{usersFile: usersFile}
25 m := make(map[string]bool)
26 atomic.StorePointer(&um.m, unsafe.Pointer(&m)) // #nosec G103
28 logger.Printf("using authenticated emails file %s", usersFile)
29 WatchForUpdates(usersFile, done, func() {
30 um.LoadAuthenticatedEmailsFile()
33 um.LoadAuthenticatedEmailsFile()
38// IsValid checks if an email is allowed
39func (um *UserMap) IsValid(email string) (result bool) {
40 m := *(*map[string]bool)(atomic.LoadPointer(&um.m))
45// LoadAuthenticatedEmailsFile loads the authenticated emails file from disk
46// and parses the contents as CSV
47func (um *UserMap) LoadAuthenticatedEmailsFile() {
48 r, err := os.Open(um.usersFile)
50 logger.Fatalf("failed opening authenticated-emails-file=%q, %s", um.usersFile, err)
52 defer func(c io.Closer) {
55 logger.Fatalf("Error closing authenticated emails file: %s", cerr)
58 csvReader := csv.NewReader(r)
60 csvReader.Comment = '#'
61 csvReader.TrimLeadingSpace = true
62 records, err := csvReader.ReadAll()
64 logger.Errorf("error reading authenticated-emails-file=%q, %s", um.usersFile, err)
67 updated := make(map[string]bool)
68 for _, r := range records {
69 address := strings.ToLower(strings.TrimSpace(r[0]))
70 updated[address] = true
72 atomic.StorePointer(&um.m, unsafe.Pointer(&updated)) // #nosec G103
75func newValidatorImpl(domains []string, usersFile string,
76 done <-chan bool, onUpdate func()) func(string) bool {
77 validUsers := NewUserMap(usersFile, done, onUpdate)
80 for i, domain := range domains {
85 domains[i] = strings.ToLower(domain)
88 validator := func(email string) (valid bool) {
92 email = strings.ToLower(email)
93 valid = isEmailValidWithDomains(email, domains)
95 valid = validUsers.IsValid(email)
105// NewValidator constructs a function to validate email addresses
106func NewValidator(domains []string, usersFile string) func(string) bool {
107 return newValidatorImpl(domains, usersFile, nil, func() {})
110// isEmailValidWithDomains checks if the authenticated email is validated against the provided domain
111func isEmailValidWithDomains(email string, allowedDomains []string) bool {
112 for _, domain := range allowedDomains {
113 // allow if the domain is perfect suffix match with the email
114 if strings.HasSuffix(email, "@"+domain) {
118 // allow if the domain is prefixed with . and
119 // the last element (split on @) has the suffix as the domain
120 atoms := strings.Split(email, "@")
121 if strings.HasPrefix(domain, ".") && strings.HasSuffix(atoms[len(atoms)-1], domain) {
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list