fixed some bugs with auth and accept functions
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user