You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.1 KiB
82 lines
2.1 KiB
package main |
|
|
|
import ( |
|
"encoding/hex" |
|
"net/http" |
|
"strings" |
|
|
|
"git.mleku.dev/mleku/nostr/httpauth" |
|
"lol.mleku.dev/chk" |
|
) |
|
|
|
// AuthMiddleware provides NIP-98 authentication for the admin API. |
|
type AuthMiddleware struct { |
|
owners map[string]struct{} |
|
} |
|
|
|
// NewAuthMiddleware creates a new auth middleware with the given owner pubkeys. |
|
func NewAuthMiddleware(owners []string) *AuthMiddleware { |
|
ownerMap := make(map[string]struct{}, len(owners)) |
|
for _, o := range owners { |
|
// Normalize to lowercase hex |
|
ownerMap[strings.ToLower(o)] = struct{}{} |
|
} |
|
return &AuthMiddleware{owners: ownerMap} |
|
} |
|
|
|
// RequireAuth wraps a handler to require NIP-98 authentication from an owner. |
|
func (a *AuthMiddleware) RequireAuth(next http.HandlerFunc) http.HandlerFunc { |
|
return func(w http.ResponseWriter, r *http.Request) { |
|
// Validate NIP-98 authentication |
|
valid, pubkeyBytes, err := httpauth.CheckAuth(r) |
|
if chk.E(err) || !valid { |
|
errorMsg := "NIP-98 authentication required" |
|
if err != nil { |
|
errorMsg = err.Error() |
|
} |
|
http.Error(w, errorMsg, http.StatusUnauthorized) |
|
return |
|
} |
|
|
|
// Convert pubkey bytes to hex string |
|
pubkeyHex := hex.EncodeToString(pubkeyBytes) |
|
|
|
// Check if pubkey is in owners list |
|
if !a.IsOwner(pubkeyHex) { |
|
http.Error(w, "Not authorized - owner access required", http.StatusForbidden) |
|
return |
|
} |
|
|
|
// Authentication successful, call the next handler |
|
next(w, r) |
|
} |
|
} |
|
|
|
// IsOwner checks if the given pubkey is in the owners list. |
|
func (a *AuthMiddleware) IsOwner(pubkey string) bool { |
|
if len(a.owners) == 0 { |
|
// No owners configured - deny all access |
|
return false |
|
} |
|
_, ok := a.owners[strings.ToLower(pubkey)] |
|
return ok |
|
} |
|
|
|
// AddOwner adds a pubkey to the owners list. |
|
func (a *AuthMiddleware) AddOwner(pubkey string) { |
|
a.owners[strings.ToLower(pubkey)] = struct{}{} |
|
} |
|
|
|
// RemoveOwner removes a pubkey from the owners list. |
|
func (a *AuthMiddleware) RemoveOwner(pubkey string) { |
|
delete(a.owners, strings.ToLower(pubkey)) |
|
} |
|
|
|
// Owners returns the list of owner pubkeys. |
|
func (a *AuthMiddleware) Owners() []string { |
|
owners := make([]string, 0, len(a.owners)) |
|
for o := range a.owners { |
|
owners = append(owners, o) |
|
} |
|
return owners |
|
}
|
|
|