fixed some bugs with auth and accept functions

This commit is contained in:
2025-04-25 17:59:44 -01:06
parent 3066fb1b84
commit 5452b130a1
9 changed files with 47 additions and 40 deletions

View File

@@ -253,10 +253,10 @@ func (r *T) HandleL2Queries(c context.T, evMap map[string]*event.T, item *badger
func (r *T) UpdateAccessed(accessed map[string]struct{}) {
var err error
for ser := range accessed {
seri := serial.New([]byte(ser))
now := timestamp.Now()
for ser := range accessed {
if err = r.Update(func(txn *badger.Txn) (err error) {
seri := serial.New([]byte(ser))
key := GetCounterKey(seri)
it := txn.NewIterator(badger.IteratorOptions{})
defer it.Close()

View File

@@ -2,7 +2,6 @@ package realy
import (
"bytes"
"fmt"
"realy.mleku.dev/chk"
"realy.mleku.dev/context"
@@ -17,16 +16,14 @@ import (
func (s *Server) acceptEvent(c context.T, evt *event.T, authedPubkey []byte,
remote string) (accept bool, notice string, afterSave func()) {
authRequired := s.AuthRequired()
s.Lock()
defer s.Unlock()
// if the authenticator is enabled we require auth to accept events
if !s.AuthRequired() && len(s.owners) == 0 {
if authRequired && len(s.owners) == 0 {
log.W.F("%s auth not required and no ACL enabled, accepting event %0x", remote, evt.Id)
return true, "", nil
}
if len(authedPubkey) != 32 || s.AuthRequired() {
notice = fmt.Sprintf("client not authed with auth required %s", remote)
log.I.F("%s %s", remote, notice)
return false, notice, nil
}
// check ACL
if len(s.owners) > 0 {
// if one of the follows of the owners or follows of the follows changes
@@ -118,7 +115,7 @@ func (s *Server) acceptEvent(c context.T, evt *event.T, authedPubkey []byte,
}
// if auth is enabled and there is no moderators we just check that the pubkey
// has been loaded via the auth function.
if len(authedPubkey) == schnorr.PubKeyBytesLen && s.AuthRequired() {
if len(authedPubkey) == schnorr.PubKeyBytesLen && authRequired {
notice = "auth required but user not authed"
return
}

View File

@@ -15,13 +15,14 @@ func (s *Server) AcceptReq(c context.T, hr *http.Request, id []byte,
modified bool) {
log.T.F("%s AcceptReq pubkey %0x", remote, authedPubkey)
if s.PublicReadable() && !s.AuthRequired() {
authRequired := s.AuthRequired()
if s.PublicReadable() && !authRequired {
log.W.F("%s accept req because public readable and not auth required", remote)
allowed = ff
ok = true
}
if len(s.Owners()) == 0 && !s.AuthRequired() {
if len(s.Owners()) == 0 && !authRequired {
log.W.F("%s accept req because no access control is enabled", remote)
allowed = ff
ok = true
@@ -42,6 +43,7 @@ func (s *Server) AcceptReq(c context.T, hr *http.Request, id []byte,
}
s.Unlock()
// if the authed pubkey was not found, reject the request.
log.W.F("%s reject req because %0x not on owner follow list", remote, authedPubkey)
return
}
// if auth is enabled and there is no moderators we just check that the pubkey

View File

@@ -22,12 +22,13 @@ var (
func (s *Server) addEvent(c context.T, ev *event.T,
authedPubkey []byte, remote string) (accepted bool, message []byte) {
authRequired := s.AuthRequired()
if ev == nil {
log.I.F("empty event")
return false, reason.Invalid.F("empty event")
}
// don't allow storing event with protected marker as per nip-70 with auth enabled.
if (s.AuthRequired() || !s.PublicReadable()) && ev.Tags.ContainsProtectedMarker() {
if (authRequired || !s.PublicReadable()) && ev.Tags.ContainsProtectedMarker() {
if len(authedPubkey) == 0 || !bytes.Equal(ev.Pubkey, authedPubkey) {
return false,
[]byte(fmt.Sprintf("event with relay marker tag '-' (nip-70 protected event) "+
@@ -55,8 +56,6 @@ func (s *Server) addEvent(c context.T, ev *event.T,
}
}
}
var authRequired bool
authRequired = s.AuthRequired()
// notify subscribers
publish.P.Deliver(authRequired, s.PublicReadable(), ev)
accepted = true

View File

@@ -99,7 +99,8 @@ func (s *Server) CheckOwnerLists(c context.T) {
var err error
var evs []*event.T
// need to search DB for moderator npub follow lists, followed npubs are allowed access.
if len(s.followed) < 1 {
lf := len(s.followed)
if lf < 1 {
log.T.F("regenerating followed list")
// add the owners themselves of course
for i := range s.owners {

View File

@@ -58,7 +58,7 @@ func (a *A) HandleEvent(c context.T, req []byte, srv interfaces.Server,
}
var reason []byte
ok, reason = srv.AddEvent(c, env.T, a.Listener.Req(), a.Listener.AuthedBytes(), remote)
log.T.F("event added %v", ok)
log.T.F("%s <- event added %v", remote, ok)
if err = okenvelope.NewFrom(env.Id(), ok, reason).Write(a.Listener); chk.E(err) {
return
}

View File

@@ -26,7 +26,7 @@ func (a *A) HandleMessage(msg []byte, remote string) {
case eventenvelope.L:
notice = a.HandleEvent(a.Context(), rem, a.Server, remote)
case reqenvelope.L:
notice = a.HandleReq(a.Context(), rem, a.Server, remote)
notice = a.HandleReq(a.Context(), rem, a.Server, a.Listener.AuthedBytes(), remote)
case closeenvelope.L:
notice = a.HandleClose(rem, a.Server)
case authenvelope.L:

View File

@@ -27,9 +27,7 @@ import (
"realy.mleku.dev/tag"
)
func (a *A) HandleReq(
c context.T, req []byte, srv interfaces.Server,
remote string) (r []byte) {
func (a *A) HandleReq(c context.T, req []byte, srv interfaces.Server, aut []byte, remote string) (r []byte) {
sto := srv.Storage()
var err error
@@ -43,12 +41,14 @@ func (a *A) HandleReq(
}
allowed := env.Filters
var accepted, modified bool
authRequired := srv.AuthRequired()
authRequested := a.Listener.AuthRequested()
allowed, accepted, modified = srv.AcceptReq(c, a.Listener.Req(), env.Subscription.T,
env.Filters, []byte(a.Listener.Authed()), remote)
if !accepted || allowed == nil || modified {
if srv.AuthRequired() && !a.Listener.AuthRequested() {
if authRequired && !authRequested {
a.Listener.RequestAuth()
if _, err = a.AuthRequiredResponse(env, remote); chk.E(err) {
if _, err = a.AuthRequiredResponse(env, remote, aut); chk.E(err) {
return
}
if !modified {
@@ -59,10 +59,9 @@ func (a *A) HandleReq(
var notice []byte
if allowed != env.Filters {
defer func() {
if srv.AuthRequired() &&
!a.Listener.AuthRequested() {
if authRequired && !authRequested {
a.Listener.RequestAuth()
if notice, err = a.AuthRequiredResponse(env, remote); chk.E(err) {
if notice, err = a.AuthRequiredResponse(env, remote, aut); chk.E(err) {
return
}
return
@@ -80,8 +79,8 @@ func (a *A) HandleReq(
}
i = *f.Limit
}
if srv.AuthRequired() && f.Kinds.IsPrivileged() {
if notice, err = a.HandleAuthPrivilege(env, f, remote); chk.E(err) {
if authRequired && f.Kinds.IsPrivileged() {
if notice, err = a.HandleAuthPrivilege(env, f, a.Listener.AuthedBytes(), remote); chk.E(err) {
return
}
}
@@ -143,13 +142,13 @@ func (a *A) HandleReq(
return
}
func (a *A) HandleAuthPrivilege(env *reqenvelope.T, f *filter.T, remote string) (notice []byte, err error) {
func (a *A) HandleAuthPrivilege(env *reqenvelope.T, f *filter.T, aut []byte, remote string) (notice []byte, err error) {
log.T.F("privileged request\n%s", f.Serialize())
senders := f.Authors
receivers := f.Tags.GetAll(tag.New("#p"))
switch {
case len(a.Listener.Authed()) == 0:
if notice, err = a.AuthRequiredResponse(env, remote); chk.E(err) {
if notice, err = a.AuthRequiredResponse(env, remote, aut); chk.E(err) {
return
}
return
@@ -199,19 +198,24 @@ func (a *A) FilterPrivileged(c context.T, sto store.I, aut []byte, events event.
func (a *A) CheckPrivilege(events event.Ts, f *filter.T, env *reqenvelope.T,
srv interfaces.Server, aut []byte, remote string) (evs event.Ts, notice []byte, err error) {
authRequired := srv.AuthRequired()
isPrivileged := f.Kinds.IsPrivileged()
for _, ev := range events {
// if auth is required, kind is privileged and there is no authed pubkey, skip
if srv.AuthRequired() && ev.Kind.IsPrivileged() && len(aut) == 0 {
if notice, err = a.AuthRequiredResponse(env, remote); chk.E(err) {
if authRequired && isPrivileged && len(aut) == 0 {
log.I.F("privileged and not authed")
if notice, err = a.AuthRequiredResponse(env, remote, aut); chk.E(err) {
return
}
return
}
// if the authed pubkey is not present in the pubkey or p tags, skip
receivers := f.Tags.GetAll(tag.New("#p"))
if ev.Kind.IsPrivileged() && (!bytes.Equal(ev.Pubkey, aut) ||
if isPrivileged && !(bytes.Equal(ev.Pubkey, aut) ||
!receivers.ContainsAny([]byte("#p"), tag.New(a.Listener.AuthedBytes()))) {
if notice, err = a.AuthRequiredResponse(env, remote); chk.E(err) {
log.I.F("%v && (%v || %v)", isPrivileged, !bytes.Equal(ev.Pubkey, aut), !receivers.ContainsAny([]byte("#p"), tag.New(a.Listener.AuthedBytes())))
if notice, err = a.AuthRequiredResponse(env, remote, aut); chk.E(err) {
return
}
return
@@ -240,14 +244,16 @@ func (a *A) WriteEvents(events event.Ts, env *reqenvelope.T, i int) (err error)
return
}
func (a *A) AuthRequiredResponse(env *reqenvelope.T, remote string) (notice []byte, err error) {
func (a *A) AuthRequiredResponse(env *reqenvelope.T, remote string, aut []byte) (notice []byte, err error) {
if err = closedenvelope.NewFrom(env.Subscription,
reason.AuthRequired.F(privilegedClosedNotice)).Write(a.Listener); chk.E(err) {
}
log.I.F("requesting auth from client from %s", remote)
if len(aut) < 1 {
log.I.F("requesting auth from client from %s %0x", remote, a.Listener.AuthedBytes())
if err = authenvelope.NewChallengeWith(a.Listener.Challenge()).Write(a.Listener); chk.E(err) {
return
}
}
notice = reason.Restricted.F(privilegedNotice)
return
}

View File

@@ -88,8 +88,10 @@ func (a *A) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// log.I.F("requesting auth from %s", remote)
// a.Listener.RequestAuth()
// }
if a.Server.AuthRequired() && a.Listener.AuthRequested() && len(a.Listener.Authed()) == 0 {
log.T.F("requesting auth from client again from %s", a.Listener.RealRemote())
if a.Server.AuthRequired() || len(a.Owners()) > 0 ||
!a.Server.PublicReadable() {
log.T.F("requesting auth from client from %s", a.Listener.RealRemote())
a.Listener.RequestAuth()
if err = authenvelope.NewChallengeWith(a.Listener.Challenge()).Write(a.Listener); chk.E(err) {
return
}