+72
-26
api/tangled/cbor_gen.go
+72
-26
api/tangled/cbor_gen.go
···
5803
5803
fieldCount--
5804
5804
}
5805
5805
5806
+
if t.Labels == nil {
5807
+
fieldCount--
5808
+
}
5809
+
5806
5810
if t.Source == nil {
5807
5811
fieldCount--
5808
5812
}
···
5880
5884
return err
5881
5885
}
5882
5886
5883
-
// t.Owner (string) (string)
5884
-
if len("owner") > 1000000 {
5885
-
return xerrors.Errorf("Value in field \"owner\" was too long")
5886
-
}
5887
+
// t.Labels ([]string) (slice)
5888
+
if t.Labels != nil {
5889
+
5890
+
if len("labels") > 1000000 {
5891
+
return xerrors.Errorf("Value in field \"labels\" was too long")
5892
+
}
5893
+
5894
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("labels"))); err != nil {
5895
+
return err
5896
+
}
5897
+
if _, err := cw.WriteString(string("labels")); err != nil {
5898
+
return err
5899
+
}
5887
5900
5888
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil {
5889
-
return err
5890
-
}
5891
-
if _, err := cw.WriteString(string("owner")); err != nil {
5892
-
return err
5893
-
}
5901
+
if len(t.Labels) > 8192 {
5902
+
return xerrors.Errorf("Slice value in field t.Labels was too long")
5903
+
}
5904
+
5905
+
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Labels))); err != nil {
5906
+
return err
5907
+
}
5908
+
for _, v := range t.Labels {
5909
+
if len(v) > 1000000 {
5910
+
return xerrors.Errorf("Value in field v was too long")
5911
+
}
5894
5912
5895
-
if len(t.Owner) > 1000000 {
5896
-
return xerrors.Errorf("Value in field t.Owner was too long")
5897
-
}
5913
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
5914
+
return err
5915
+
}
5916
+
if _, err := cw.WriteString(string(v)); err != nil {
5917
+
return err
5918
+
}
5898
5919
5899
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil {
5900
-
return err
5901
-
}
5902
-
if _, err := cw.WriteString(string(t.Owner)); err != nil {
5903
-
return err
5920
+
}
5904
5921
}
5905
5922
5906
5923
// t.Source (string) (string)
···
6098
6115
6099
6116
t.LexiconTypeID = string(sval)
6100
6117
}
6101
-
// t.Owner (string) (string)
6102
-
case "owner":
6118
+
// t.Labels ([]string) (slice)
6119
+
case "labels":
6120
+
6121
+
maj, extra, err = cr.ReadHeader()
6122
+
if err != nil {
6123
+
return err
6124
+
}
6125
+
6126
+
if extra > 8192 {
6127
+
return fmt.Errorf("t.Labels: array too large (%d)", extra)
6128
+
}
6129
+
6130
+
if maj != cbg.MajArray {
6131
+
return fmt.Errorf("expected cbor array")
6132
+
}
6133
+
6134
+
if extra > 0 {
6135
+
t.Labels = make([]string, extra)
6136
+
}
6137
+
6138
+
for i := 0; i < int(extra); i++ {
6139
+
{
6140
+
var maj byte
6141
+
var extra uint64
6142
+
var err error
6143
+
_ = maj
6144
+
_ = extra
6145
+
_ = err
6103
6146
6104
-
{
6105
-
sval, err := cbg.ReadStringWithMax(cr, 1000000)
6106
-
if err != nil {
6107
-
return err
6147
+
{
6148
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
6149
+
if err != nil {
6150
+
return err
6151
+
}
6152
+
6153
+
t.Labels[i] = string(sval)
6154
+
}
6155
+
6108
6156
}
6109
-
6110
-
t.Owner = string(sval)
6111
6157
}
6112
6158
// t.Source (string) (string)
6113
6159
case "source":
+3
-2
api/tangled/tangledrepo.go
+3
-2
api/tangled/tangledrepo.go
···
22
22
Description *string `json:"description,omitempty" cborgen:"description,omitempty"`
23
23
// knot: knot where the repo was created
24
24
Knot string `json:"knot" cborgen:"knot"`
25
+
// labels: List of labels that this repo subscribes to
26
+
Labels []string `json:"labels,omitempty" cborgen:"labels,omitempty"`
25
27
// name: name of the repo
26
-
Name string `json:"name" cborgen:"name"`
27
-
Owner string `json:"owner" cborgen:"owner"`
28
+
Name string `json:"name" cborgen:"name"`
28
29
// source: source of the repo
29
30
Source *string `json:"source,omitempty" cborgen:"source,omitempty"`
30
31
// spindle: CI runner to send jobs to and receive results from
-3
appview/repo/repo.go
-3
appview/repo/repo.go
···
313
313
Val: &tangled.Repo{
314
314
Knot: f.Knot,
315
315
Name: f.Name,
316
-
Owner: user.Did,
317
316
CreatedAt: f.Created.Format(time.RFC3339),
318
317
Description: &newDescription,
319
318
Spindle: &f.Spindle,
···
926
925
Val: &tangled.Repo{
927
926
Knot: f.Knot,
928
927
Name: f.Name,
929
-
Owner: user.Did,
930
928
CreatedAt: f.Created.Format(time.RFC3339),
931
929
Description: &f.Description,
932
930
Spindle: spindlePtr,
···
1612
1610
Knot: repo.Knot,
1613
1611
Name: repo.Name,
1614
1612
CreatedAt: createdAt,
1615
-
Owner: user.Did,
1616
1613
Source: &sourceAt,
1617
1614
}},
1618
1615
})
-3
appview/state/router.go
-3
appview/state/router.go
-1
appview/state/state.go
-1
appview/state/state.go
-6
appview/strings/strings.go
-6
appview/strings/strings.go
···
9
9
"time"
10
10
11
11
"tangled.sh/tangled.sh/core/api/tangled"
12
-
"tangled.sh/tangled.sh/core/appview/config"
13
12
"tangled.sh/tangled.sh/core/appview/db"
14
13
"tangled.sh/tangled.sh/core/appview/middleware"
15
14
"tangled.sh/tangled.sh/core/appview/notify"
16
15
"tangled.sh/tangled.sh/core/appview/oauth"
17
16
"tangled.sh/tangled.sh/core/appview/pages"
18
17
"tangled.sh/tangled.sh/core/appview/pages/markup"
19
-
"tangled.sh/tangled.sh/core/eventconsumer"
20
18
"tangled.sh/tangled.sh/core/idresolver"
21
-
"tangled.sh/tangled.sh/core/rbac"
22
19
"tangled.sh/tangled.sh/core/tid"
23
20
24
21
"github.com/bluesky-social/indigo/api/atproto"
···
32
29
Db *db.DB
33
30
OAuth *oauth.OAuth
34
31
Pages *pages.Pages
35
-
Config *config.Config
36
-
Enforcer *rbac.Enforcer
37
32
IdResolver *idresolver.Resolver
38
33
Logger *slog.Logger
39
-
Knotstream *eventconsumer.Consumer
40
34
Notifier notify.Notifier
41
35
}
42
36
+2
-2
knotserver/ingester.go
+2
-2
knotserver/ingester.go
···
141
141
return fmt.Errorf("rejected pull record: not this knot, %s != %s", repo.Knot, h.c.Server.Hostname)
142
142
}
143
143
144
-
didSlashRepo, err := securejoin.SecureJoin(repo.Owner, repo.Name)
144
+
didSlashRepo, err := securejoin.SecureJoin(ident.DID.String(), repo.Name)
145
145
if err != nil {
146
146
return fmt.Errorf("failed to construct relative repo path: %w", err)
147
147
}
···
191
191
Kind: string(workflow.TriggerKindPullRequest),
192
192
PullRequest: &trigger,
193
193
Repo: &tangled.Pipeline_TriggerRepo{
194
-
Did: repo.Owner,
194
+
Did: ident.DID.String(),
195
195
Knot: repo.Knot,
196
196
Repo: repo.Name,
197
197
},
-36
knotserver/util.go
-36
knotserver/util.go
···
1
1
package knotserver
2
2
3
3
import (
4
-
"net/http"
5
-
"os"
6
-
"path/filepath"
7
-
8
4
"github.com/bluesky-social/indigo/atproto/syntax"
9
-
securejoin "github.com/cyphar/filepath-securejoin"
10
-
"github.com/go-chi/chi/v5"
11
5
)
12
-
13
-
func didPath(r *http.Request) string {
14
-
did := chi.URLParam(r, "did")
15
-
name := chi.URLParam(r, "name")
16
-
path, _ := securejoin.SecureJoin(did, name)
17
-
filepath.Clean(path)
18
-
return path
19
-
}
20
-
21
-
func getDescription(path string) (desc string) {
22
-
db, err := os.ReadFile(filepath.Join(path, "description"))
23
-
if err == nil {
24
-
desc = string(db)
25
-
} else {
26
-
desc = ""
27
-
}
28
-
return
29
-
}
30
-
func setContentDisposition(w http.ResponseWriter, name string) {
31
-
h := "inline; filename=\"" + name + "\""
32
-
w.Header().Add("Content-Disposition", h)
33
-
}
34
-
35
-
func setGZipMIME(w http.ResponseWriter) {
36
-
setMIME(w, "application/gzip")
37
-
}
38
-
39
-
func setMIME(w http.ResponseWriter, mime string) {
40
-
w.Header().Add("Content-Type", mime)
41
-
}
42
6
43
7
var TIDClock = syntax.NewTIDClock(0)
44
8
+8
-5
lexicons/repo/repo.json
+8
-5
lexicons/repo/repo.json
···
12
12
"required": [
13
13
"name",
14
14
"knot",
15
-
"owner",
16
15
"createdAt"
17
16
],
18
17
"properties": {
19
18
"name": {
20
19
"type": "string",
21
20
"description": "name of the repo"
22
-
},
23
-
"owner": {
24
-
"type": "string",
25
-
"format": "did"
26
21
},
27
22
"knot": {
28
23
"type": "string",
···
41
36
"type": "string",
42
37
"format": "uri",
43
38
"description": "source of the repo"
39
+
},
40
+
"labels": {
41
+
"type": "array",
42
+
"description": "List of labels that this repo subscribes to",
43
+
"items": {
44
+
"type": "string",
45
+
"format": "at-uri"
46
+
}
44
47
},
45
48
"createdAt": {
46
49
"type": "string",
+5
-5
spindle/ingester.go
+5
-5
spindle/ingester.go
···
162
162
163
163
// no spindle configured for this repo
164
164
if record.Spindle == nil {
165
-
l.Info("no spindle configured", "did", record.Owner, "name", record.Name)
165
+
l.Info("no spindle configured", "name", record.Name)
166
166
return nil
167
167
}
168
168
169
169
// this repo did not want this spindle
170
170
if *record.Spindle != domain {
171
-
l.Info("different spindle configured", "did", record.Owner, "name", record.Name, "spindle", *record.Spindle, "domain", domain)
171
+
l.Info("different spindle configured", "name", record.Name, "spindle", *record.Spindle, "domain", domain)
172
172
return nil
173
173
}
174
174
175
175
// add this repo to the watch list
176
-
if err := s.db.AddRepo(record.Knot, record.Owner, record.Name); err != nil {
176
+
if err := s.db.AddRepo(record.Knot, did, record.Name); err != nil {
177
177
l.Error("failed to add repo", "error", err)
178
178
return fmt.Errorf("failed to add repo: %w", err)
179
179
}
180
180
181
-
didSlashRepo, err := securejoin.SecureJoin(record.Owner, record.Name)
181
+
didSlashRepo, err := securejoin.SecureJoin(did, record.Name)
182
182
if err != nil {
183
183
return err
184
184
}
185
185
186
186
// add repo to rbac
187
-
if err := s.e.AddRepo(record.Owner, rbac.ThisServer, didSlashRepo); err != nil {
187
+
if err := s.e.AddRepo(did, rbac.ThisServer, didSlashRepo); err != nil {
188
188
l.Error("failed to add repo to enforcer", "error", err)
189
189
return fmt.Errorf("failed to add repo: %w", err)
190
190
}
+1
-1
spindle/xrpc/add_secret.go
+1
-1
spindle/xrpc/add_secret.go
+1
-1
spindle/xrpc/list_secrets.go
+1
-1
spindle/xrpc/list_secrets.go
+1
-1
spindle/xrpc/remove_secret.go
+1
-1
spindle/xrpc/remove_secret.go