package main import ( "bufio" "net/http" "os" "strings" "gitlab.com/nyarla/go-crypt" ) type User struct { Username string `json:"username"` } type Htpasswd struct { entries map[string]string } func NewHtpasswd(path string) (*Htpasswd, error) { if fd, err := os.Open(path); err != nil { return nil, err } else { defer fd.Close() htpasswd := Htpasswd{ map[string]string{}, } scanner := bufio.NewScanner(fd) for scanner.Scan() { line := strings.SplitN(strings.TrimSpace(scanner.Text()), ":", 2) if len(line) == 2 && len(line[1]) > 2 { htpasswd.entries[line[0]] = line[1] } } if err := scanner.Err(); err != nil { return nil, err } return &htpasswd, nil } } func (h Htpasswd) Authenticate(username, password string) *User { if hash, ok := h.entries[username]; !ok { return nil } else if crypt.Crypt(password, hash[:2]) != hash { return nil } else { var u = User{username} return &u } } /// Request authentication func Authenticate(htpasswd Htpasswd, r *http.Request) *User { // Authenticate the user if any if username, password, ok := r.BasicAuth(); ok { return htpasswd.Authenticate(username, password) } else { return nil } } /// Page rules type AuthFunction func(*User, []string) bool func PublicPage(u *User, args []string) bool { return true } func PrivatePage(u *User, args []string) bool { return u != nil }