Skip to content

Commit

Permalink
update handling to not require auth unless path is auth required on w…
Browse files Browse the repository at this point in the history
…eb server
  • Loading branch information
mleku committed Nov 29, 2024
1 parent 6492652 commit fb9eef2
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 72 deletions.
133 changes: 73 additions & 60 deletions realy/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"realy.lol/sha256"
)

func (s *Server) HandleAdmin(w http.ResponseWriter, r *http.Request) {
func (s *Server) HTTPAuth(r *http.Request) (authed bool) {
username, password, ok := r.BasicAuth()
if ok {
log.I.S(username, password)
Expand All @@ -35,72 +35,85 @@ func (s *Server) HandleAdmin(w http.ResponseWriter, r *http.Request) {
expectedUsernameHash[:]) == 1
passwordMatch := subtle.ConstantTimeCompare(passwordHash[:],
expectedPasswordHash[:]) == 1
if usernameMatch && passwordMatch {
return true
}
}
return
}

// If the username and password are correct, then call
// the next handler in the chain. Make sure to return
// afterwards, so that none of the code below is run.
if !usernameMatch || !passwordMatch {
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
func (s *Server) AuthFail(w http.ResponseWriter) {
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
}

func (s *Server) HandleAdmin(w http.ResponseWriter, r *http.Request) {
switch {
case strings.HasPrefix(r.URL.Path, "/export"):
if ok := s.HTTPAuth(r); !ok {
s.AuthFail(w)
return
}
switch {
case strings.HasPrefix(r.URL.Path, "/export"):
log.I.F("export of event data requested on admin port")
store := s.relay.Storage(context.Bg())
if strings.Count(r.URL.Path, "/") > 1 {
split := strings.Split(r.URL.Path, "/")
// there should be 3 for a valid path, an empty, "export" and the final parameter
if len(split) != 3 {
fmt.Fprintf(w, "incorrectly formatted export parameter: '%s'",
r.URL.Path)
return
}
switch split[2] {
case "users":
// todo: naughty reaching through interface here lol... but the relay
// implementation does have this feature and another impl may not. Perhaps add
// a new interface for grabbing the relay's allowed list, and rename things to
// be more clear. And add a method for fetching such a relay's allowed writers.
if rl, ok := s.relay.(*app.Relay); ok {
follows := make([]B, 0, len(rl.Followed))
for f := range rl.Followed {
follows = append(follows, B(f))
}
store.Export(s.Ctx, w, follows...)
log.I.F("export of event data requested on admin port")
store := s.relay.Storage(context.Bg())
if strings.Count(r.URL.Path, "/") > 1 {
split := strings.Split(r.URL.Path, "/")
// there should be 3 for a valid path, an empty, "export" and the final parameter
if len(split) != 3 {
fmt.Fprintf(w, "incorrectly formatted export parameter: '%s'",
r.URL.Path)
return
}
switch split[2] {
case "users":
// todo: naughty reaching through interface here lol... but the relay
// implementation does have this feature and another impl may not. Perhaps add
// a new interface for grabbing the relay's allowed list, and rename things to
// be more clear. And add a method for fetching such a relay's allowed writers.
if rl, ok := s.relay.(*app.Relay); ok {
follows := make([]B, 0, len(rl.Followed))
for f := range rl.Followed {
follows = append(follows, B(f))
}
default:
// this should be a hyphen separated list of hexadecimal pubkey values
var exportPubkeys []B
pubkeys := strings.Split(split[2], "-")
for _, pubkey := range pubkeys {
// check they are valid hex
pk, err := hex.Dec(pubkey)
if err != nil {
log.E.F("invalid public key '%s' in parameters", pubkey)
continue
}
exportPubkeys = append(exportPubkeys, pk)
store.Export(s.Ctx, w, follows...)
}
default:
// this should be a hyphen separated list of hexadecimal pubkey values
var exportPubkeys []B
pubkeys := strings.Split(split[2], "-")
for _, pubkey := range pubkeys {
// check they are valid hex
pk, err := hex.Dec(pubkey)
if err != nil {
log.E.F("invalid public key '%s' in parameters", pubkey)
continue
}
store.Export(s.Ctx, w, exportPubkeys...)
exportPubkeys = append(exportPubkeys, pk)
}
} else {
store.Export(s.Ctx, w)
store.Export(s.Ctx, w, exportPubkeys...)
}
case strings.HasPrefix(r.URL.Path, "/import"):
log.I.F("import of event data requested on admin port %s", r.RequestURI)
store := s.relay.Storage(context.Bg())
read := io.LimitReader(r.Body, r.ContentLength)
store.Import(read)
case strings.HasPrefix(r.URL.Path, "/shutdown"):
fmt.Fprintf(w, "shutting down")
defer r.Body.Close()
s.Shutdown()
default:
fmt.Fprintf(w, `todo: make help info page`)
} else {
store.Export(s.Ctx, w)
}
case strings.HasPrefix(r.URL.Path, "/import"):
if ok := s.HTTPAuth(r); !ok {
s.AuthFail(w)
return
}
log.I.F("import of event data requested on admin port %s", r.RequestURI)
store := s.relay.Storage(context.Bg())
read := io.LimitReader(r.Body, r.ContentLength)
store.Import(read)
case strings.HasPrefix(r.URL.Path, "/shutdown"):
if ok := s.HTTPAuth(r); !ok {
s.AuthFail(w)
return
}
} else {
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
fmt.Fprintf(w, "shutting down")
defer r.Body.Close()
s.Shutdown()
default:
fmt.Fprintf(w, "todo: realy web interface page\n\n")
s.HandleNIP11(w, r)
}
}
2 changes: 1 addition & 1 deletion realy/handlerelayinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (s *Server) HandleNIP11(w http.ResponseWriter, r *http.Request) {
Nips: supportedNIPs,
Software: "https://realy.lol",
Version: version,
Limitation: ri.Limits{MaxLimit: s.maxLimit},
Limitation: ri.Limits{MaxLimit: s.maxLimit, AuthRequired: s.authRequired},
Icon: "https://cdn.satellite.earth/ac9778868fbf23b63c47c769a74e163377e6ea94d3f0f31711931663d035c4f6.png",
}
}
Expand Down
2 changes: 1 addition & 1 deletion realy/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.2.20
v1.2.21
20 changes: 10 additions & 10 deletions relayinfo/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,20 @@ type Pub struct {
// T is the realy information document.
type T struct {
Name string `json:"name"`
Description string `json:"description"`
PubKey string `json:"pubkey"`
Description string `json:"description,omitempty"`
PubKey string `json:"pubkey,omitempty"`
Contact string `json:"contact,omitempty"`
Nips number.List `json:"supported_nips"`
Software string `json:"software"`
Version string `json:"version"`
Limitation Limits `json:"limitation"`
Retention any `json:"retention"`
RelayCountries []string `json:"relay_countries"`
LanguageTags []string `json:"language_tags"`
Tags []string `json:"tags"`
PostingPolicy string `json:"posting_policy"`
PaymentsURL string `json:"payments_url"`
Fees Fees `json:"fees"`
Limitation Limits `json:"limitation,omitempty"`
Retention any `json:"retention,omitempty"`
RelayCountries []string `json:"relay_countries,omitempty"`
LanguageTags []string `json:"language_tags,omitempty"`
Tags []string `json:"tags,omitempty"`
PostingPolicy string `json:"posting_policy,omitempty"`
PaymentsURL string `json:"payments_url,omitempty"`
Fees *Fees `json:"fees,omitempty"`
Icon string `json:"icon"`
sync.Mutex
}
Expand Down

0 comments on commit fb9eef2

Please sign in to comment.