(cfg config.BasicAuth)
| 18 | } |
| 19 | |
| 20 | func newBasicAuth(cfg config.BasicAuth) (AuthScheme, error) { |
| 21 | bad := func(err error) { |
| 22 | log.Println("[WARN] Error processing a line in an htpasswd file:", err) |
| 23 | } |
| 24 | |
| 25 | secrets, err := htpasswd.New(cfg.File, htpasswd.DefaultSystems, bad) |
| 26 | if err != nil { |
| 27 | return nil, err |
| 28 | } |
| 29 | |
| 30 | if cfg.Refresh > 0 { |
| 31 | stat, err := os.Stat(cfg.File) |
| 32 | if err != nil { |
| 33 | return nil, err |
| 34 | } |
| 35 | cfg.ModTime = stat.ModTime() |
| 36 | |
| 37 | go func() { |
| 38 | cleared := false |
| 39 | ticker := time.NewTicker(cfg.Refresh).C |
| 40 | for range ticker { |
| 41 | stat, err := os.Stat(cfg.File) |
| 42 | if err != nil { |
| 43 | log.Println("[WARN] Error accessing htpasswd file:", err) |
| 44 | if !cleared { |
| 45 | err = secrets.ReloadFromReader(&bytes.Buffer{}, bad) |
| 46 | if err != nil { |
| 47 | log.Println("[WARN] Error clearing the htpasswd credentials:", err) |
| 48 | } else { |
| 49 | log.Println("[INFO] The htpasswd credentials have been cleared") |
| 50 | cleared = true |
| 51 | } |
| 52 | } |
| 53 | continue |
| 54 | } |
| 55 | |
| 56 | // refresh the htpasswd file only if its modification time has changed |
| 57 | // even if the new htpasswd file is older than previously loaded |
| 58 | if cfg.ModTime != stat.ModTime() { |
| 59 | if err := secrets.Reload(bad); err == nil { |
| 60 | log.Println("[INFO] The htpasswd file has been successfully reloaded") |
| 61 | cfg.ModTime = stat.ModTime() |
| 62 | cleared = false |
| 63 | } else { |
| 64 | log.Println("[WARN] Error reloading htpasswd file:", err) |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | }() |
| 69 | } |
| 70 | |
| 71 | return &basic{ |
| 72 | secrets: secrets, |
| 73 | realm: cfg.Realm, |
| 74 | }, nil |
| 75 | } |
| 76 | |
| 77 | func (b *basic) Authorized(request *http.Request, response http.ResponseWriter) bool { |
no outgoing calls