Fix some access logic
This commit is contained in:
+4
-4
@@ -57,7 +57,7 @@ func (bl *BlossomStore) Enable(instance *Instance) {
|
|||||||
return true, "file too large", 413
|
return true, "file too large", 413
|
||||||
}
|
}
|
||||||
|
|
||||||
if auth == nil || !instance.Management.IsPubkeyAllowed(auth.PubKey) {
|
if auth == nil || !instance.Management.HasAccess(auth.PubKey) {
|
||||||
return true, "unauthorized", 403
|
return true, "unauthorized", 403
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ func (bl *BlossomStore) Enable(instance *Instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
backend.RejectGet = func(ctx context.Context, auth *nostr.Event, sha256 string, ext string) (bool, string, int) {
|
backend.RejectGet = func(ctx context.Context, auth *nostr.Event, sha256 string, ext string) (bool, string, int) {
|
||||||
if auth == nil || !instance.Management.IsPubkeyAllowed(auth.PubKey) {
|
if auth == nil || !instance.Management.HasAccess(auth.PubKey) {
|
||||||
return true, "unauthorized", 403
|
return true, "unauthorized", 403
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ func (bl *BlossomStore) Enable(instance *Instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
backend.RejectList = func(ctx context.Context, auth *nostr.Event, pubkey nostr.PubKey) (bool, string, int) {
|
backend.RejectList = func(ctx context.Context, auth *nostr.Event, pubkey nostr.PubKey) (bool, string, int) {
|
||||||
if auth == nil || !instance.Management.IsPubkeyAllowed(auth.PubKey) {
|
if auth == nil || !instance.Management.HasAccess(auth.PubKey) {
|
||||||
return true, "unauthorized", 403
|
return true, "unauthorized", 403
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ func (bl *BlossomStore) Enable(instance *Instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
backend.RejectDelete = func(ctx context.Context, auth *nostr.Event, sha256 string, ext string) (bool, string, int) {
|
backend.RejectDelete = func(ctx context.Context, auth *nostr.Event, sha256 string, ext string) (bool, string, int) {
|
||||||
if auth == nil || !instance.Management.IsPubkeyAllowed(auth.PubKey) {
|
if auth == nil || !instance.Management.HasAccess(auth.PubKey) {
|
||||||
return true, "unauthorized", 403
|
return true, "unauthorized", 403
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-20
@@ -95,13 +95,13 @@ func (config *Config) IsOwner(pubkey nostr.PubKey) bool {
|
|||||||
return pubkey.Hex() == config.Info.Pubkey
|
return pubkey.Hex() == config.Info.Pubkey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) GetRolesForPubkey(pubkey nostr.PubKey) []Role {
|
func (config *Config) IsAdmin(pubkey nostr.PubKey) bool {
|
||||||
roles := make([]Role, 0)
|
return config.IsOwner(pubkey) || config.IsSelf(pubkey)
|
||||||
for name, role := range config.Roles {
|
}
|
||||||
if name == "member" {
|
|
||||||
roles = append(roles, role)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
func (config *Config) GetAssignedRoles(pubkey nostr.PubKey) []Role {
|
||||||
|
roles := make([]Role, 0)
|
||||||
|
for _, role := range config.Roles {
|
||||||
if slices.Contains(role.Pubkeys, pubkey.Hex()) {
|
if slices.Contains(role.Pubkeys, pubkey.Hex()) {
|
||||||
roles = append(roles, role)
|
roles = append(roles, role)
|
||||||
}
|
}
|
||||||
@@ -110,18 +110,25 @@ func (config *Config) GetRolesForPubkey(pubkey nostr.PubKey) []Role {
|
|||||||
return roles
|
return roles
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) CanManage(pubkey nostr.PubKey) bool {
|
func (config *Config) GetAllRoles(pubkey nostr.PubKey) []Role {
|
||||||
for _, role := range config.GetRolesForPubkey(pubkey) {
|
roles := make([]Role, 0)
|
||||||
if role.CanManage {
|
for name, role := range config.Roles {
|
||||||
return true
|
if name == "member" {
|
||||||
|
roles = append(roles, role)
|
||||||
|
} else if slices.Contains(role.Pubkeys, pubkey.Hex()) {
|
||||||
|
roles = append(roles, role)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return roles
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) CanInvite(pubkey nostr.PubKey) bool {
|
func (config *Config) CanInvite(pubkey nostr.PubKey) bool {
|
||||||
for _, role := range config.GetRolesForPubkey(pubkey) {
|
if config.IsAdmin(pubkey) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, role := range config.GetAllRoles(pubkey) {
|
||||||
if role.CanInvite {
|
if role.CanInvite {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -130,17 +137,15 @@ func (config *Config) CanInvite(pubkey nostr.PubKey) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) IsAdmin(pubkey nostr.PubKey) bool {
|
func (config *Config) CanManage(pubkey nostr.PubKey) bool {
|
||||||
if config.IsOwner(pubkey) {
|
if config.IsAdmin(pubkey) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.IsSelf(pubkey) {
|
for _, role := range config.GetAllRoles(pubkey) {
|
||||||
return true
|
if role.CanManage {
|
||||||
}
|
return true
|
||||||
|
}
|
||||||
if config.CanManage(pubkey) {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
+66
-66
@@ -137,7 +137,7 @@ func (instance *Instance) Cleanup() {
|
|||||||
func (instance *Instance) StripSignature(ctx context.Context, event nostr.Event) nostr.Event {
|
func (instance *Instance) StripSignature(ctx context.Context, event nostr.Event) nostr.Event {
|
||||||
pubkey, _ := khatru.GetAuthed(ctx)
|
pubkey, _ := khatru.GetAuthed(ctx)
|
||||||
|
|
||||||
if instance.Config.Policy.StripSignatures && !instance.Config.IsAdmin(pubkey) {
|
if instance.Config.Policy.StripSignatures && !instance.Config.CanManage(pubkey) {
|
||||||
var zeroSig [64]byte
|
var zeroSig [64]byte
|
||||||
event.Sig = zeroSig
|
event.Sig = zeroSig
|
||||||
}
|
}
|
||||||
@@ -159,7 +159,7 @@ func (instance *Instance) AllowRecipientEvent(event nostr.Event) bool {
|
|||||||
if recipientTag != nil {
|
if recipientTag != nil {
|
||||||
pubkey, err := nostr.PubKeyFromHex(recipientTag[1])
|
pubkey, err := nostr.PubKeyFromHex(recipientTag[1])
|
||||||
|
|
||||||
if err == nil && instance.Management.IsPubkeyAllowed(pubkey) {
|
if err == nil && instance.Management.HasAccess(pubkey) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,6 +251,68 @@ func (instance *Instance) DeleteEvent(ctx context.Context, id nostr.ID) error {
|
|||||||
return instance.Events.DeleteEvent(id)
|
return instance.Events.DeleteEvent(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Requests
|
||||||
|
|
||||||
|
func (instance *Instance) OnRequest(ctx context.Context, filter nostr.Filter) (reject bool, msg string) {
|
||||||
|
pubkey, ok := khatru.GetAuthed(ctx)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return true, "auth-required: authentication is required for access"
|
||||||
|
}
|
||||||
|
|
||||||
|
if !instance.Management.HasAccess(pubkey) {
|
||||||
|
return true, "restricted: you are not a member of this relay"
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (instance *Instance) QueryStored(ctx context.Context, filter nostr.Filter) iter.Seq[nostr.Event] {
|
||||||
|
return func(yield func(nostr.Event) bool) {
|
||||||
|
if khatru.IsInternalCall(ctx) {
|
||||||
|
for event := range instance.Events.QueryEvents(filter, 0) {
|
||||||
|
if !yield(event) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pubkey, _ := khatru.GetAuthed(ctx)
|
||||||
|
|
||||||
|
if slices.Contains(filter.Kinds, RELAY_INVITE) && instance.Config.CanInvite(pubkey) {
|
||||||
|
if !yield(instance.StripSignature(ctx, instance.GenerateInviteEvent(pubkey))) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for event := range instance.Events.QueryEvents(filter, 1000) {
|
||||||
|
if instance.IsWriteOnlyEvent(event) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
h := GetGroupIDFromEvent(event)
|
||||||
|
|
||||||
|
if h != "" {
|
||||||
|
if !instance.Config.Groups.Enabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !instance.Groups.HasAccess(h, pubkey) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !instance.Config.Groups.Enabled && slices.Contains(nip29.MetadataEventKinds, event.Kind) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !yield(instance.StripSignature(ctx, event)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Event publishing
|
// Event publishing
|
||||||
|
|
||||||
func (instance *Instance) OnEvent(ctx context.Context, event nostr.Event) (reject bool, msg string) {
|
func (instance *Instance) OnEvent(ctx context.Context, event nostr.Event) (reject bool, msg string) {
|
||||||
@@ -270,7 +332,7 @@ func (instance *Instance) OnEvent(ctx context.Context, event nostr.Event) (rejec
|
|||||||
return instance.Management.ValidateJoinRequest(event)
|
return instance.Management.ValidateJoinRequest(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !instance.Management.IsPubkeyAllowed(pubkey) {
|
if !instance.Management.HasAccess(pubkey) {
|
||||||
return true, "restricted: you are not a member of this relay"
|
return true, "restricted: you are not a member of this relay"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +344,7 @@ func (instance *Instance) OnEvent(ctx context.Context, event nostr.Event) (rejec
|
|||||||
return true, "invalid: group metadata cannot be set directly"
|
return true, "invalid: group metadata cannot be set directly"
|
||||||
}
|
}
|
||||||
|
|
||||||
if slices.Contains(nip29.ModerationEventKinds, event.Kind) && !instance.Config.IsAdmin(event.PubKey) {
|
if slices.Contains(nip29.ModerationEventKinds, event.Kind) && !instance.Config.CanManage(event.PubKey) {
|
||||||
return true, "restricted: you are not authorized to manage groups"
|
return true, "restricted: you are not authorized to manage groups"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,65 +431,3 @@ func (instance *Instance) OnEventSaved(ctx context.Context, event nostr.Event) {
|
|||||||
instance.Groups.DeleteGroup(GetGroupIDFromEvent(event))
|
instance.Groups.DeleteGroup(GetGroupIDFromEvent(event))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Requests
|
|
||||||
|
|
||||||
func (instance *Instance) OnRequest(ctx context.Context, filter nostr.Filter) (reject bool, msg string) {
|
|
||||||
pubkey, ok := khatru.GetAuthed(ctx)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
return true, "auth-required: authentication is required for access"
|
|
||||||
}
|
|
||||||
|
|
||||||
if !instance.Management.IsPubkeyAllowed(pubkey) {
|
|
||||||
return true, "restricted: you are not a member of this relay"
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (instance *Instance) QueryStored(ctx context.Context, filter nostr.Filter) iter.Seq[nostr.Event] {
|
|
||||||
return func(yield func(nostr.Event) bool) {
|
|
||||||
if khatru.IsInternalCall(ctx) {
|
|
||||||
for event := range instance.Events.QueryEvents(filter, 0) {
|
|
||||||
if !yield(event) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pubkey, _ := khatru.GetAuthed(ctx)
|
|
||||||
|
|
||||||
if slices.Contains(filter.Kinds, RELAY_INVITE) && instance.Config.CanInvite(pubkey) {
|
|
||||||
if !yield(instance.StripSignature(ctx, instance.GenerateInviteEvent(pubkey))) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for event := range instance.Events.QueryEvents(filter, 1000) {
|
|
||||||
if instance.IsWriteOnlyEvent(event) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
h := GetGroupIDFromEvent(event)
|
|
||||||
|
|
||||||
if h != "" {
|
|
||||||
if !instance.Config.Groups.Enabled {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if !instance.Groups.HasAccess(h, pubkey) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !instance.Config.Groups.Enabled && slices.Contains(nip29.MetadataEventKinds, event.Kind) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if !yield(instance.StripSignature(ctx, event)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+22
-14
@@ -259,20 +259,8 @@ func (m *ManagementStore) GetAllowedPubkeyItems() []nip86.PubKeyReason {
|
|||||||
return reasons
|
return reasons
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ManagementStore) IsPubkeyAllowed(pubkey nostr.PubKey) bool {
|
|
||||||
if m.Config.IsOwner(pubkey) || m.Config.IsSelf(pubkey) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
for range m.Config.GetRolesForPubkey(pubkey) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.IsMember(pubkey)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ManagementStore) AllowPubkey(pubkey nostr.PubKey) error {
|
func (m *ManagementStore) AllowPubkey(pubkey nostr.PubKey) error {
|
||||||
if m.IsPubkeyAllowed(pubkey) {
|
if m.HasAccess(pubkey) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,6 +275,18 @@ func (m *ManagementStore) AllowPubkey(pubkey nostr.PubKey) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ManagementStore) HasAccess(pubkey nostr.PubKey) bool {
|
||||||
|
if m.Config.IsAdmin(pubkey) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for range m.Config.GetAssignedRoles(pubkey) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.IsMember(pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
// Joining
|
// Joining
|
||||||
|
|
||||||
func (m *ManagementStore) ValidateJoinRequest(event nostr.Event) (reject bool, err string) {
|
func (m *ManagementStore) ValidateJoinRequest(event nostr.Event) (reject bool, err string) {
|
||||||
@@ -319,7 +319,15 @@ func (m *ManagementStore) Enable(instance *Instance) {
|
|||||||
instance.Relay.ManagementAPI.OnAPICall = func(ctx context.Context, mp nip86.MethodParams) (reject bool, msg string) {
|
instance.Relay.ManagementAPI.OnAPICall = func(ctx context.Context, mp nip86.MethodParams) (reject bool, msg string) {
|
||||||
pubkey, ok := khatru.GetAuthed(ctx)
|
pubkey, ok := khatru.GetAuthed(ctx)
|
||||||
|
|
||||||
if ok && m.Config.CanManage(pubkey) {
|
if !ok {
|
||||||
|
return true, "blocked: please authenticate in order to manage this relay"
|
||||||
|
}
|
||||||
|
|
||||||
|
if !m.HasAccess(pubkey) {
|
||||||
|
return true, "blocked: you are not a member of this relay"
|
||||||
|
}
|
||||||
|
|
||||||
|
if !m.Config.CanManage(pubkey) {
|
||||||
return true, "blocked: only relay admins can manage this relay."
|
return true, "blocked: only relay admins can manage this relay."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user