+72
-26
api/tangled/cbor_gen.go
+72
-26
api/tangled/cbor_gen.go
···
5812
5812
fieldCount--
5813
5813
}
5814
5814
5815
+
if t.Labels == nil {
5816
+
fieldCount--
5817
+
}
5818
+
5815
5819
if t.Source == nil {
5816
5820
fieldCount--
5817
5821
}
···
5889
5893
return err
5890
5894
}
5891
5895
5892
-
// t.Owner (string) (string)
5893
-
if len("owner") > 1000000 {
5894
-
return xerrors.Errorf("Value in field \"owner\" was too long")
5895
-
}
5896
+
// t.Labels ([]string) (slice)
5897
+
if t.Labels != nil {
5898
+
5899
+
if len("labels") > 1000000 {
5900
+
return xerrors.Errorf("Value in field \"labels\" was too long")
5901
+
}
5902
+
5903
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("labels"))); err != nil {
5904
+
return err
5905
+
}
5906
+
if _, err := cw.WriteString(string("labels")); err != nil {
5907
+
return err
5908
+
}
5896
5909
5897
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("owner"))); err != nil {
5898
-
return err
5899
-
}
5900
-
if _, err := cw.WriteString(string("owner")); err != nil {
5901
-
return err
5902
-
}
5910
+
if len(t.Labels) > 8192 {
5911
+
return xerrors.Errorf("Slice value in field t.Labels was too long")
5912
+
}
5913
+
5914
+
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Labels))); err != nil {
5915
+
return err
5916
+
}
5917
+
for _, v := range t.Labels {
5918
+
if len(v) > 1000000 {
5919
+
return xerrors.Errorf("Value in field v was too long")
5920
+
}
5903
5921
5904
-
if len(t.Owner) > 1000000 {
5905
-
return xerrors.Errorf("Value in field t.Owner was too long")
5906
-
}
5922
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
5923
+
return err
5924
+
}
5925
+
if _, err := cw.WriteString(string(v)); err != nil {
5926
+
return err
5927
+
}
5907
5928
5908
-
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Owner))); err != nil {
5909
-
return err
5910
-
}
5911
-
if _, err := cw.WriteString(string(t.Owner)); err != nil {
5912
-
return err
5929
+
}
5913
5930
}
5914
5931
5915
5932
// t.Source (string) (string)
···
6107
6124
6108
6125
t.LexiconTypeID = string(sval)
6109
6126
}
6110
-
// t.Owner (string) (string)
6111
-
case "owner":
6127
+
// t.Labels ([]string) (slice)
6128
+
case "labels":
6129
+
6130
+
maj, extra, err = cr.ReadHeader()
6131
+
if err != nil {
6132
+
return err
6133
+
}
6134
+
6135
+
if extra > 8192 {
6136
+
return fmt.Errorf("t.Labels: array too large (%d)", extra)
6137
+
}
6138
+
6139
+
if maj != cbg.MajArray {
6140
+
return fmt.Errorf("expected cbor array")
6141
+
}
6142
+
6143
+
if extra > 0 {
6144
+
t.Labels = make([]string, extra)
6145
+
}
6146
+
6147
+
for i := 0; i < int(extra); i++ {
6148
+
{
6149
+
var maj byte
6150
+
var extra uint64
6151
+
var err error
6152
+
_ = maj
6153
+
_ = extra
6154
+
_ = err
6112
6155
6113
-
{
6114
-
sval, err := cbg.ReadStringWithMax(cr, 1000000)
6115
-
if err != nil {
6116
-
return err
6156
+
{
6157
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
6158
+
if err != nil {
6159
+
return err
6160
+
}
6161
+
6162
+
t.Labels[i] = string(sval)
6163
+
}
6164
+
6117
6165
}
6118
-
6119
-
t.Owner = string(sval)
6120
6166
}
6121
6167
// t.Source (string) (string)
6122
6168
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,
···
950
949
Val: &tangled.Repo{
951
950
Knot: f.Knot,
952
951
Name: f.Name,
953
-
Owner: user.Did,
954
952
CreatedAt: f.Created.Format(time.RFC3339),
955
953
Description: &f.Description,
956
954
Spindle: spindlePtr,
···
1636
1634
Knot: repo.Knot,
1637
1635
Name: repo.Name,
1638
1636
CreatedAt: createdAt,
1639
-
Owner: user.Did,
1640
1637
Source: &sourceAt,
1641
1638
}},
1642
1639
})
-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