+1
-1
appview/ingester.go
+1
-1
appview/ingester.go
···
1008
1008
if !ok {
1009
1009
return fmt.Errorf("failed to find label def for key: %s, expected: %q", o.OperandKey, slices.Collect(maps.Keys(actx.Defs)))
1010
1010
}
1011
-
if err := i.Validator.ValidateLabelOp(def, &o); err != nil {
1011
+
if err := i.Validator.ValidateLabelOp(def, repo, &o); err != nil {
1012
1012
return fmt.Errorf("failed to validate labelop: %w", err)
1013
1013
}
1014
1014
}
+11
-1
appview/labels/labels.go
+11
-1
appview/labels/labels.go
···
23
23
"tangled.org/core/appview/validator"
24
24
"tangled.org/core/appview/xrpcclient"
25
25
"tangled.org/core/log"
26
+
"tangled.org/core/rbac"
26
27
"tangled.org/core/tid"
27
28
)
28
29
···
32
33
db *db.DB
33
34
logger *slog.Logger
34
35
validator *validator.Validator
36
+
enforcer *rbac.Enforcer
35
37
}
36
38
37
39
func New(
···
39
41
pages *pages.Pages,
40
42
db *db.DB,
41
43
validator *validator.Validator,
44
+
enforcer *rbac.Enforcer,
42
45
) *Labels {
43
46
logger := log.New("labels")
44
47
···
48
51
db: db,
49
52
logger: logger,
50
53
validator: validator,
54
+
enforcer: enforcer,
51
55
}
52
56
}
53
57
···
86
90
repoAt := r.Form.Get("repo")
87
91
subjectUri := r.Form.Get("subject")
88
92
93
+
repo, err := db.GetRepo(l.db, db.FilterEq("at_uri", repoAt))
94
+
if err != nil {
95
+
fail("Failed to get repository.", err)
96
+
return
97
+
}
98
+
89
99
// find all the labels that this repo subscribes to
90
100
repoLabels, err := db.GetRepoLabels(l.db, db.FilterEq("repo_at", repoAt))
91
101
if err != nil {
···
157
167
158
168
for i := range labelOps {
159
169
def := actx.Defs[labelOps[i].OperandKey]
160
-
if err := l.validator.ValidateLabelOp(def, &labelOps[i]); err != nil {
170
+
if err := l.validator.ValidateLabelOp(def, repo, &labelOps[i]); err != nil {
161
171
fail(fmt.Sprintf("Invalid form data: %s", err), err)
162
172
return
163
173
}
+1
-1
appview/state/router.go
+1
-1
appview/state/router.go
+1
-1
appview/state/state.go
+1
-1
appview/state/state.go
···
79
79
cache := cache.New(config.Redis.Addr)
80
80
sess := session.New(cache)
81
81
oauth := oauth.NewOAuth(config, sess)
82
-
validator := validator.New(d, res)
82
+
validator := validator.New(d, res, enforcer)
83
83
84
84
posthog, err := posthog.NewWithConfig(config.Posthog.ApiKey, posthog.Config{Endpoint: config.Posthog.Endpoint})
85
85
if err != nil {
+15
-1
appview/validator/label.go
+15
-1
appview/validator/label.go
···
95
95
return nil
96
96
}
97
97
98
-
func (v *Validator) ValidateLabelOp(labelDef *models.LabelDefinition, labelOp *models.LabelOp) error {
98
+
func (v *Validator) ValidateLabelOp(labelDef *models.LabelDefinition, repo *models.Repo, labelOp *models.LabelOp) error {
99
99
if labelDef == nil {
100
100
return fmt.Errorf("label definition is required")
101
101
}
102
+
if repo == nil {
103
+
return fmt.Errorf("repo is required")
104
+
}
102
105
if labelOp == nil {
103
106
return fmt.Errorf("label operation is required")
107
+
}
108
+
109
+
// validate permissions: only collaborators can apply labels currently
110
+
//
111
+
// TODO: introduce a repo:triage permission
112
+
ok, err := v.enforcer.IsPushAllowed(labelOp.Did, repo.Knot, repo.DidSlashRepo())
113
+
if err != nil {
114
+
return fmt.Errorf("failed to enforce permissions: %w", err)
115
+
}
116
+
if !ok {
117
+
return fmt.Errorf("unauhtorized label operation")
104
118
}
105
119
106
120
expectedKey := labelDef.AtUri().String()
+4
-1
appview/validator/validator.go
+4
-1
appview/validator/validator.go
···
4
4
"tangled.org/core/appview/db"
5
5
"tangled.org/core/appview/pages/markup"
6
6
"tangled.org/core/idresolver"
7
+
"tangled.org/core/rbac"
7
8
)
8
9
9
10
type Validator struct {
10
11
db *db.DB
11
12
sanitizer markup.Sanitizer
12
13
resolver *idresolver.Resolver
14
+
enforcer *rbac.Enforcer
13
15
}
14
16
15
-
func New(db *db.DB, res *idresolver.Resolver) *Validator {
17
+
func New(db *db.DB, res *idresolver.Resolver, enforcer *rbac.Enforcer) *Validator {
16
18
return &Validator{
17
19
db: db,
18
20
sanitizer: markup.NewSanitizer(),
19
21
resolver: res,
22
+
enforcer: enforcer,
20
23
}
21
24
}