tinyrelayfile
tinyrelay/internal/daemon/custom_views_access.go/

internal/daemon/custom_views_access.go raw
1package daemon
2
3import (
4 "context"
5 "encoding/json"
6 "strconv"
7 "strings"
8 "time"
9
10 "github.com/FelineStateMachine/tinyrelay/internal/event"
11 "github.com/FelineStateMachine/tinyrelay/internal/relay"
12 "github.com/FelineStateMachine/tinyrelay/internal/views"
13)
14
15func (t *customViewService) artifactEventVisible(ctx context.Context, e event.Event, s relay.Session) bool {
16 if t.records == nil || e.PubKey != t.records.PublicKey() {
17 return true
18 }
19 d := event.Tag(e, "d")
20 if !strings.HasPrefix(d, "bind.ws/view/") {
21 return true
22 }
23 var view, hash string
24 if err := t.store.DB().QueryRowContext(ctx, `SELECT view,hash FROM custom_view_artifacts WHERE event_id=?`, e.ID).Scan(&view, &hash); err != nil {
25 return false
26 }
27 if d != "bind.ws/view/"+view+"/"+hash {
28 return false
29 }
30 refs := map[string]bool{}
31 for _, tag := range e.Tags {
32 if len(tag) == 2 && (tag[0] == "e" || tag[0] == "a") {
33 refs[tag[1]] = true
34 }
35 }
36 if len(refs) == 0 {
37 return false
38 }
39 sources, ok := t.artifactSourceRows(ctx, view, hash)
40 if !ok {
41 return false
42 }
43 for _, source := range sources {
44 if !refs[source] || !t.sourceVisible(ctx, source, s, hash) {
45 return false
46 }
47 delete(refs, source)
48 }
49 return len(sources) > 0 && len(refs) == 0
50}
51
52func (t *customViewService) artifactHTTPSourceVisible(ctx context.Context, view, hash string, s relay.Session) bool {
53 sources, ok := t.artifactSourceRows(ctx, view, hash)
54 if !ok {
55 return false
56 }
57 for _, source := range sources {
58 if t.sourceVisible(ctx, source, s, hash) {
59 return true
60 }
61 }
62 return false
63}
64
65func (t *customViewService) artifactSourceRows(ctx context.Context, view, hash string) ([]string, bool) {
66 rows, err := t.store.DB().QueryContext(ctx, `SELECT source FROM custom_view_sources WHERE view=? AND hash=?`, view, hash)
67 if err != nil {
68 return nil, false
69 }
70 defer rows.Close()
71 var sources []string
72 for rows.Next() {
73 var source string
74 if rows.Scan(&source) != nil {
75 _ = rows.Close()
76 return nil, false
77 }
78 sources = append(sources, source)
79 }
80 if rows.Err() != nil {
81 return nil, false
82 }
83 return sources, true
84}
85
86func (t *customViewService) sourceVisible(ctx context.Context, source string, s relay.Session, artifactHash string) bool {
87 if t.gate == nil {
88 return false
89 }
90 var raw string
91 if tag := viewSourceTag(source); tag[0] == "a" {
92 parts := strings.SplitN(source, ":", 3)
93 if len(parts) != 3 {
94 return false
95 }
96 if err := t.store.DB().QueryRowContext(ctx, `SELECT raw FROM events WHERE kind=? AND pubkey=? AND d=? AND (expires=0 OR expires>?) ORDER BY created_at DESC,id ASC LIMIT 1`, event.KIND_REPO_STATE, parts[1], parts[2], time.Now().Unix()).Scan(&raw); err != nil {
97 return false
98 }
99 } else if err := t.store.DB().QueryRowContext(ctx, `SELECT raw FROM events WHERE id=? AND (expires=0 OR expires>?)`, source, time.Now().Unix()).Scan(&raw); err != nil {
100 return false
101 }
102 var sourceEvent event.Event
103 if err := json.Unmarshal([]byte(raw), &sourceEvent); err != nil || !t.gate.CanSee(ctx, sourceEvent, s, nil) {
104 return false
105 }
106 if strings.HasPrefix(source, strconv.Itoa(event.KIND_REPO_STATE)+":") && artifactHash != "" {
107 blocks, err := t.sourceBlocks(ctx, sourceEvent)
108 if err != nil {
109 return false
110 }
111 for _, block := range blocks {
112 if views.Hash(block.Lang, block.Source) == artifactHash {
113 return true
114 }
115 }
116 return false
117 }
118 return true
119}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs