restructure config to allow user credentials to update multiple records
This commit separates user credentials from resource record configs to allow user credentials to be used for multiple records instead of one.
This commit is contained in:
parent
7f1500d53d
commit
451776bde0
4 changed files with 116 additions and 38 deletions
51
web.go
51
web.go
|
|
@ -9,25 +9,25 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func isAuthenticated(cfg *Config, r *http.Request) *RRConfig {
|
||||
user, pw, ok := r.BasicAuth()
|
||||
func isAuthenticated(cfg *Config, r *http.Request) *User {
|
||||
username, password, ok := r.BasicAuth()
|
||||
if !ok {
|
||||
// no basic auth header detected
|
||||
return nil
|
||||
}
|
||||
|
||||
entry, ok := cfg.rrconfigs[user]
|
||||
user, ok := cfg.users[username]
|
||||
if !ok {
|
||||
// non-existent username
|
||||
return nil
|
||||
}
|
||||
|
||||
err := bcrypt.CompareHashAndPassword([]byte(entry.Password), []byte(pw))
|
||||
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
|
||||
if err != nil {
|
||||
log.Printf("Config contains invalid password hash for user %q", user)
|
||||
log.Printf("Config contains invalid password hash for user %q", username)
|
||||
return nil
|
||||
}
|
||||
return entry
|
||||
return user
|
||||
}
|
||||
|
||||
func getIpAddress(r *http.Request) net.IP {
|
||||
|
|
@ -61,25 +61,36 @@ func getIpAddress(r *http.Request) net.IP {
|
|||
return net.ParseIP(addr)
|
||||
}
|
||||
|
||||
// returns api-response on failure
|
||||
func verifyHostname(entry *RRConfig, hostname string) string {
|
||||
// returns api-response on failure and RRConfig on success
|
||||
func verifyHostname(cfg *Config, user *User, hostname string) (string, *RRConfig) {
|
||||
if len(hostname) <= 0 {
|
||||
return "nohost"
|
||||
return "nohost", nil
|
||||
}
|
||||
|
||||
// TODO: allow single user to update multiple hostnames
|
||||
// TODO: return ntfqdn -> differentiate between 'hostname doesnt exist' and
|
||||
// 'hostname is not fqdn'
|
||||
if hostname != entry.Hostname {
|
||||
return "nohost"
|
||||
// check whether the authenticated user is allowed to update the dns record
|
||||
_, ok := user.records[hostname]
|
||||
if !ok {
|
||||
return "nohost", nil
|
||||
}
|
||||
return ""
|
||||
|
||||
// this should not fail as it is verified in LoadConfig, but better be sure
|
||||
entry, ok := cfg.rrconfigs[hostname]
|
||||
if !ok {
|
||||
return "nohost", nil
|
||||
}
|
||||
|
||||
// TODO: return notfqdn -> differentiate between 'hostname doesnt exist' and
|
||||
// 'hostname is not fqdn'
|
||||
if hostname != entry.Recordname {
|
||||
return "nohost", nil
|
||||
}
|
||||
return "", entry
|
||||
}
|
||||
|
||||
func RequestHandler(cfg *Config) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
userdata := isAuthenticated(cfg, r)
|
||||
if userdata == nil {
|
||||
user := isAuthenticated(cfg, r)
|
||||
if user == nil {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="dyndns"`)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("badauth"))
|
||||
|
|
@ -98,7 +109,7 @@ func RequestHandler(cfg *Config) func(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
hostname := r.URL.Query().Get("hostname")
|
||||
response := verifyHostname(userdata, hostname)
|
||||
response, entry := verifyHostname(cfg, user, hostname)
|
||||
if response != "" {
|
||||
fmt.Fprintln(w, response)
|
||||
return
|
||||
|
|
@ -110,12 +121,12 @@ func RequestHandler(cfg *Config) func(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if !requiresRRUpdate(userdata, ipaddr) {
|
||||
if !requiresRRUpdate(entry, ipaddr) {
|
||||
fmt.Fprintf(w, "nochg %s\n", ipaddr.String())
|
||||
return
|
||||
}
|
||||
|
||||
err := updateRR(userdata, ipaddr)
|
||||
err := updateRR(entry, ipaddr)
|
||||
if err != nil {
|
||||
log.Printf("updating RR failed: %s", err)
|
||||
fmt.Fprintln(w, "911")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue