+32
-32
appview/issues/issues.go
+32
-32
appview/issues/issues.go
···
81
82
func (rp *Issues) RepoSingleIssue(w http.ResponseWriter, r *http.Request) {
83
l := rp.logger.With("handler", "RepoSingleIssue")
84
-
user := rp.oauth.GetUser(r)
85
f, err := rp.repoResolver.Resolve(r)
86
if err != nil {
87
l.Error("failed to get repo and knot", "err", err)
···
102
103
userReactions := map[models.ReactionKind]bool{}
104
if user != nil {
105
-
userReactions = db.GetReactionStatusMap(rp.db, user.Did, issue.AtUri())
106
}
107
108
backlinks, err := db.GetBacklinks(rp.db, issue.AtUri())
···
143
144
func (rp *Issues) EditIssue(w http.ResponseWriter, r *http.Request) {
145
l := rp.logger.With("handler", "EditIssue")
146
-
user := rp.oauth.GetUser(r)
147
148
issue, ok := r.Context().Value("issue").(*models.Issue)
149
if !ok {
···
182
return
183
}
184
185
-
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueNSID, user.Did, newIssue.Rkey)
186
if err != nil {
187
l.Error("failed to get record", "err", err)
188
rp.pages.Notice(w, noticeId, "Failed to edit issue, no record found on PDS.")
···
191
192
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
193
Collection: tangled.RepoIssueNSID,
194
-
Repo: user.Did,
195
Rkey: newIssue.Rkey,
196
SwapRecord: ex.Cid,
197
Record: &lexutil.LexiconTypeDecoder{
···
292
293
func (rp *Issues) CloseIssue(w http.ResponseWriter, r *http.Request) {
294
l := rp.logger.With("handler", "CloseIssue")
295
-
user := rp.oauth.GetUser(r)
296
f, err := rp.repoResolver.Resolve(r)
297
if err != nil {
298
l.Error("failed to get repo and knot", "err", err)
···
306
return
307
}
308
309
-
roles := repoinfo.RolesInRepo{Roles: rp.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo())}
310
isRepoOwner := roles.IsOwner()
311
isCollaborator := roles.IsCollaborator()
312
-
isIssueOwner := user.Did == issue.Did
313
314
// TODO: make this more granular
315
if isIssueOwner || isRepoOwner || isCollaborator {
···
326
issue.Open = false
327
328
// notify about the issue closure
329
-
rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Did), issue)
330
331
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
332
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
···
340
341
func (rp *Issues) ReopenIssue(w http.ResponseWriter, r *http.Request) {
342
l := rp.logger.With("handler", "ReopenIssue")
343
-
user := rp.oauth.GetUser(r)
344
f, err := rp.repoResolver.Resolve(r)
345
if err != nil {
346
l.Error("failed to get repo and knot", "err", err)
···
354
return
355
}
356
357
-
roles := repoinfo.RolesInRepo{Roles: rp.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo())}
358
isRepoOwner := roles.IsOwner()
359
isCollaborator := roles.IsCollaborator()
360
-
isIssueOwner := user.Did == issue.Did
361
362
if isCollaborator || isRepoOwner || isIssueOwner {
363
err := db.ReopenIssues(
···
373
issue.Open = true
374
375
// notify about the issue reopen
376
-
rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Did), issue)
377
378
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
379
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
···
387
388
func (rp *Issues) NewIssueComment(w http.ResponseWriter, r *http.Request) {
389
l := rp.logger.With("handler", "NewIssueComment")
390
-
user := rp.oauth.GetUser(r)
391
f, err := rp.repoResolver.Resolve(r)
392
if err != nil {
393
l.Error("failed to get repo and knot", "err", err)
···
416
mentions, references := rp.mentionsResolver.Resolve(r.Context(), body)
417
418
comment := models.IssueComment{
419
-
Did: user.Did,
420
Rkey: tid.TID(),
421
IssueAt: issue.AtUri().String(),
422
ReplyTo: replyTo,
···
495
496
func (rp *Issues) IssueComment(w http.ResponseWriter, r *http.Request) {
497
l := rp.logger.With("handler", "IssueComment")
498
-
user := rp.oauth.GetUser(r)
499
500
issue, ok := r.Context().Value("issue").(*models.Issue)
501
if !ok {
···
531
532
func (rp *Issues) EditIssueComment(w http.ResponseWriter, r *http.Request) {
533
l := rp.logger.With("handler", "EditIssueComment")
534
-
user := rp.oauth.GetUser(r)
535
536
issue, ok := r.Context().Value("issue").(*models.Issue)
537
if !ok {
···
557
}
558
comment := comments[0]
559
560
-
if comment.Did != user.Did {
561
-
l.Error("unauthorized comment edit", "expectedDid", comment.Did, "gotDid", user.Did)
562
http.Error(w, "you are not the author of this comment", http.StatusUnauthorized)
563
return
564
}
···
608
// rkey is optional, it was introduced later
609
if newComment.Rkey != "" {
610
// update the record on pds
611
-
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueCommentNSID, user.Did, comment.Rkey)
612
if err != nil {
613
l.Error("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey)
614
rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "Failed to update description, no record found on PDS.")
···
617
618
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
619
Collection: tangled.RepoIssueCommentNSID,
620
-
Repo: user.Did,
621
Rkey: newComment.Rkey,
622
SwapRecord: ex.Cid,
623
Record: &lexutil.LexiconTypeDecoder{
···
641
642
func (rp *Issues) ReplyIssueCommentPlaceholder(w http.ResponseWriter, r *http.Request) {
643
l := rp.logger.With("handler", "ReplyIssueCommentPlaceholder")
644
-
user := rp.oauth.GetUser(r)
645
646
issue, ok := r.Context().Value("issue").(*models.Issue)
647
if !ok {
···
677
678
func (rp *Issues) ReplyIssueComment(w http.ResponseWriter, r *http.Request) {
679
l := rp.logger.With("handler", "ReplyIssueComment")
680
-
user := rp.oauth.GetUser(r)
681
682
issue, ok := r.Context().Value("issue").(*models.Issue)
683
if !ok {
···
713
714
func (rp *Issues) DeleteIssueComment(w http.ResponseWriter, r *http.Request) {
715
l := rp.logger.With("handler", "DeleteIssueComment")
716
-
user := rp.oauth.GetUser(r)
717
718
issue, ok := r.Context().Value("issue").(*models.Issue)
719
if !ok {
···
739
}
740
comment := comments[0]
741
742
-
if comment.Did != user.Did {
743
-
l.Error("unauthorized action", "expectedDid", comment.Did, "gotDid", user.Did)
744
http.Error(w, "you are not the author of this comment", http.StatusUnauthorized)
745
return
746
}
···
769
}
770
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
771
Collection: tangled.RepoIssueCommentNSID,
772
-
Repo: user.Did,
773
Rkey: comment.Rkey,
774
})
775
if err != nil {
···
807
808
page := pagination.FromContext(r.Context())
809
810
-
user := rp.oauth.GetUser(r)
811
f, err := rp.repoResolver.Resolve(r)
812
if err != nil {
813
l.Error("failed to get repo and knot", "err", err)
···
884
}
885
886
rp.pages.RepoIssues(w, pages.RepoIssuesParams{
887
-
LoggedInUser: rp.oauth.GetUser(r),
888
RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
889
Issues: issues,
890
IssueCount: totalIssues,
···
897
898
func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) {
899
l := rp.logger.With("handler", "NewIssue")
900
-
user := rp.oauth.GetUser(r)
901
902
f, err := rp.repoResolver.Resolve(r)
903
if err != nil {
···
921
Title: r.FormValue("title"),
922
Body: body,
923
Open: true,
924
-
Did: user.Did,
925
Created: time.Now(),
926
Mentions: mentions,
927
References: references,
···
945
}
946
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
947
Collection: tangled.RepoIssueNSID,
948
-
Repo: user.Did,
949
Rkey: issue.Rkey,
950
Record: &lexutil.LexiconTypeDecoder{
951
Val: &record,
···
81
82
func (rp *Issues) RepoSingleIssue(w http.ResponseWriter, r *http.Request) {
83
l := rp.logger.With("handler", "RepoSingleIssue")
84
+
user := rp.oauth.GetMultiAccountUser(r)
85
f, err := rp.repoResolver.Resolve(r)
86
if err != nil {
87
l.Error("failed to get repo and knot", "err", err)
···
102
103
userReactions := map[models.ReactionKind]bool{}
104
if user != nil {
105
+
userReactions = db.GetReactionStatusMap(rp.db, user.Active.Did, issue.AtUri())
106
}
107
108
backlinks, err := db.GetBacklinks(rp.db, issue.AtUri())
···
143
144
func (rp *Issues) EditIssue(w http.ResponseWriter, r *http.Request) {
145
l := rp.logger.With("handler", "EditIssue")
146
+
user := rp.oauth.GetMultiAccountUser(r)
147
148
issue, ok := r.Context().Value("issue").(*models.Issue)
149
if !ok {
···
182
return
183
}
184
185
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueNSID, user.Active.Did, newIssue.Rkey)
186
if err != nil {
187
l.Error("failed to get record", "err", err)
188
rp.pages.Notice(w, noticeId, "Failed to edit issue, no record found on PDS.")
···
191
192
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
193
Collection: tangled.RepoIssueNSID,
194
+
Repo: user.Active.Did,
195
Rkey: newIssue.Rkey,
196
SwapRecord: ex.Cid,
197
Record: &lexutil.LexiconTypeDecoder{
···
292
293
func (rp *Issues) CloseIssue(w http.ResponseWriter, r *http.Request) {
294
l := rp.logger.With("handler", "CloseIssue")
295
+
user := rp.oauth.GetMultiAccountUser(r)
296
f, err := rp.repoResolver.Resolve(r)
297
if err != nil {
298
l.Error("failed to get repo and knot", "err", err)
···
306
return
307
}
308
309
+
roles := repoinfo.RolesInRepo{Roles: rp.enforcer.GetPermissionsInRepo(user.Active.Did, f.Knot, f.DidSlashRepo())}
310
isRepoOwner := roles.IsOwner()
311
isCollaborator := roles.IsCollaborator()
312
+
isIssueOwner := user.Active.Did == issue.Did
313
314
// TODO: make this more granular
315
if isIssueOwner || isRepoOwner || isCollaborator {
···
326
issue.Open = false
327
328
// notify about the issue closure
329
+
rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Active.Did), issue)
330
331
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
332
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
···
340
341
func (rp *Issues) ReopenIssue(w http.ResponseWriter, r *http.Request) {
342
l := rp.logger.With("handler", "ReopenIssue")
343
+
user := rp.oauth.GetMultiAccountUser(r)
344
f, err := rp.repoResolver.Resolve(r)
345
if err != nil {
346
l.Error("failed to get repo and knot", "err", err)
···
354
return
355
}
356
357
+
roles := repoinfo.RolesInRepo{Roles: rp.enforcer.GetPermissionsInRepo(user.Active.Did, f.Knot, f.DidSlashRepo())}
358
isRepoOwner := roles.IsOwner()
359
isCollaborator := roles.IsCollaborator()
360
+
isIssueOwner := user.Active.Did == issue.Did
361
362
if isCollaborator || isRepoOwner || isIssueOwner {
363
err := db.ReopenIssues(
···
373
issue.Open = true
374
375
// notify about the issue reopen
376
+
rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Active.Did), issue)
377
378
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
379
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
···
387
388
func (rp *Issues) NewIssueComment(w http.ResponseWriter, r *http.Request) {
389
l := rp.logger.With("handler", "NewIssueComment")
390
+
user := rp.oauth.GetMultiAccountUser(r)
391
f, err := rp.repoResolver.Resolve(r)
392
if err != nil {
393
l.Error("failed to get repo and knot", "err", err)
···
416
mentions, references := rp.mentionsResolver.Resolve(r.Context(), body)
417
418
comment := models.IssueComment{
419
+
Did: user.Active.Did,
420
Rkey: tid.TID(),
421
IssueAt: issue.AtUri().String(),
422
ReplyTo: replyTo,
···
495
496
func (rp *Issues) IssueComment(w http.ResponseWriter, r *http.Request) {
497
l := rp.logger.With("handler", "IssueComment")
498
+
user := rp.oauth.GetMultiAccountUser(r)
499
500
issue, ok := r.Context().Value("issue").(*models.Issue)
501
if !ok {
···
531
532
func (rp *Issues) EditIssueComment(w http.ResponseWriter, r *http.Request) {
533
l := rp.logger.With("handler", "EditIssueComment")
534
+
user := rp.oauth.GetMultiAccountUser(r)
535
536
issue, ok := r.Context().Value("issue").(*models.Issue)
537
if !ok {
···
557
}
558
comment := comments[0]
559
560
+
if comment.Did != user.Active.Did {
561
+
l.Error("unauthorized comment edit", "expectedDid", comment.Did, "gotDid", user.Active.Did)
562
http.Error(w, "you are not the author of this comment", http.StatusUnauthorized)
563
return
564
}
···
608
// rkey is optional, it was introduced later
609
if newComment.Rkey != "" {
610
// update the record on pds
611
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueCommentNSID, user.Active.Did, comment.Rkey)
612
if err != nil {
613
l.Error("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey)
614
rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "Failed to update description, no record found on PDS.")
···
617
618
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
619
Collection: tangled.RepoIssueCommentNSID,
620
+
Repo: user.Active.Did,
621
Rkey: newComment.Rkey,
622
SwapRecord: ex.Cid,
623
Record: &lexutil.LexiconTypeDecoder{
···
641
642
func (rp *Issues) ReplyIssueCommentPlaceholder(w http.ResponseWriter, r *http.Request) {
643
l := rp.logger.With("handler", "ReplyIssueCommentPlaceholder")
644
+
user := rp.oauth.GetMultiAccountUser(r)
645
646
issue, ok := r.Context().Value("issue").(*models.Issue)
647
if !ok {
···
677
678
func (rp *Issues) ReplyIssueComment(w http.ResponseWriter, r *http.Request) {
679
l := rp.logger.With("handler", "ReplyIssueComment")
680
+
user := rp.oauth.GetMultiAccountUser(r)
681
682
issue, ok := r.Context().Value("issue").(*models.Issue)
683
if !ok {
···
713
714
func (rp *Issues) DeleteIssueComment(w http.ResponseWriter, r *http.Request) {
715
l := rp.logger.With("handler", "DeleteIssueComment")
716
+
user := rp.oauth.GetMultiAccountUser(r)
717
718
issue, ok := r.Context().Value("issue").(*models.Issue)
719
if !ok {
···
739
}
740
comment := comments[0]
741
742
+
if comment.Did != user.Active.Did {
743
+
l.Error("unauthorized action", "expectedDid", comment.Did, "gotDid", user.Active.Did)
744
http.Error(w, "you are not the author of this comment", http.StatusUnauthorized)
745
return
746
}
···
769
}
770
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
771
Collection: tangled.RepoIssueCommentNSID,
772
+
Repo: user.Active.Did,
773
Rkey: comment.Rkey,
774
})
775
if err != nil {
···
807
808
page := pagination.FromContext(r.Context())
809
810
+
user := rp.oauth.GetMultiAccountUser(r)
811
f, err := rp.repoResolver.Resolve(r)
812
if err != nil {
813
l.Error("failed to get repo and knot", "err", err)
···
884
}
885
886
rp.pages.RepoIssues(w, pages.RepoIssuesParams{
887
+
LoggedInUser: rp.oauth.GetMultiAccountUser(r),
888
RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
889
Issues: issues,
890
IssueCount: totalIssues,
···
897
898
func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) {
899
l := rp.logger.With("handler", "NewIssue")
900
+
user := rp.oauth.GetMultiAccountUser(r)
901
902
f, err := rp.repoResolver.Resolve(r)
903
if err != nil {
···
921
Title: r.FormValue("title"),
922
Body: body,
923
Open: true,
924
+
Did: user.Active.Did,
925
Created: time.Now(),
926
Mentions: mentions,
927
References: references,
···
945
}
946
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
947
Collection: tangled.RepoIssueNSID,
948
+
Repo: user.Active.Did,
949
Rkey: issue.Rkey,
950
Record: &lexutil.LexiconTypeDecoder{
951
Val: &record,
+31
-31
appview/knots/knots.go
+31
-31
appview/knots/knots.go
···
70
}
71
72
func (k *Knots) knots(w http.ResponseWriter, r *http.Request) {
73
-
user := k.OAuth.GetUser(r)
74
registrations, err := db.GetRegistrations(
75
k.Db,
76
-
orm.FilterEq("did", user.Did),
77
)
78
if err != nil {
79
k.Logger.Error("failed to fetch knot registrations", "err", err)
···
92
func (k *Knots) dashboard(w http.ResponseWriter, r *http.Request) {
93
l := k.Logger.With("handler", "dashboard")
94
95
-
user := k.OAuth.GetUser(r)
96
-
l = l.With("user", user.Did)
97
98
domain := chi.URLParam(r, "domain")
99
if domain == "" {
···
103
104
registrations, err := db.GetRegistrations(
105
k.Db,
106
-
orm.FilterEq("did", user.Did),
107
orm.FilterEq("domain", domain),
108
)
109
if err != nil {
···
154
}
155
156
func (k *Knots) register(w http.ResponseWriter, r *http.Request) {
157
-
user := k.OAuth.GetUser(r)
158
l := k.Logger.With("handler", "register")
159
160
noticeId := "register-error"
···
175
return
176
}
177
l = l.With("domain", domain)
178
-
l = l.With("user", user.Did)
179
180
tx, err := k.Db.Begin()
181
if err != nil {
···
188
k.Enforcer.E.LoadPolicy()
189
}()
190
191
-
err = db.AddKnot(tx, domain, user.Did)
192
if err != nil {
193
l.Error("failed to insert", "err", err)
194
fail()
···
210
return
211
}
212
213
-
ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.KnotNSID, user.Did, domain)
214
var exCid *string
215
if ex != nil {
216
exCid = ex.Cid
···
219
// re-announce by registering under same rkey
220
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
221
Collection: tangled.KnotNSID,
222
-
Repo: user.Did,
223
Rkey: domain,
224
Record: &lexutil.LexiconTypeDecoder{
225
Val: &tangled.Knot{
···
250
}
251
252
// begin verification
253
-
err = serververify.RunVerification(r.Context(), domain, user.Did, k.Config.Core.Dev)
254
if err != nil {
255
l.Error("verification failed", "err", err)
256
k.Pages.HxRefresh(w)
257
return
258
}
259
260
-
err = serververify.MarkKnotVerified(k.Db, k.Enforcer, domain, user.Did)
261
if err != nil {
262
l.Error("failed to mark verified", "err", err)
263
k.Pages.HxRefresh(w)
···
275
}
276
277
func (k *Knots) delete(w http.ResponseWriter, r *http.Request) {
278
-
user := k.OAuth.GetUser(r)
279
l := k.Logger.With("handler", "delete")
280
281
noticeId := "operation-error"
···
294
// get record from db first
295
registrations, err := db.GetRegistrations(
296
k.Db,
297
-
orm.FilterEq("did", user.Did),
298
orm.FilterEq("domain", domain),
299
)
300
if err != nil {
···
322
323
err = db.DeleteKnot(
324
tx,
325
-
orm.FilterEq("did", user.Did),
326
orm.FilterEq("domain", domain),
327
)
328
if err != nil {
···
350
351
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
352
Collection: tangled.KnotNSID,
353
-
Repo: user.Did,
354
Rkey: domain,
355
})
356
if err != nil {
···
382
}
383
384
func (k *Knots) retry(w http.ResponseWriter, r *http.Request) {
385
-
user := k.OAuth.GetUser(r)
386
l := k.Logger.With("handler", "retry")
387
388
noticeId := "operation-error"
···
398
return
399
}
400
l = l.With("domain", domain)
401
-
l = l.With("user", user.Did)
402
403
// get record from db first
404
registrations, err := db.GetRegistrations(
405
k.Db,
406
-
orm.FilterEq("did", user.Did),
407
orm.FilterEq("domain", domain),
408
)
409
if err != nil {
···
419
registration := registrations[0]
420
421
// begin verification
422
-
err = serververify.RunVerification(r.Context(), domain, user.Did, k.Config.Core.Dev)
423
if err != nil {
424
l.Error("verification failed", "err", err)
425
···
437
return
438
}
439
440
-
err = serververify.MarkKnotVerified(k.Db, k.Enforcer, domain, user.Did)
441
if err != nil {
442
l.Error("failed to mark verified", "err", err)
443
k.Pages.Notice(w, noticeId, err.Error())
···
456
return
457
}
458
459
-
ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.KnotNSID, user.Did, domain)
460
var exCid *string
461
if ex != nil {
462
exCid = ex.Cid
···
465
// ignore the error here
466
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
467
Collection: tangled.KnotNSID,
468
-
Repo: user.Did,
469
Rkey: domain,
470
Record: &lexutil.LexiconTypeDecoder{
471
Val: &tangled.Knot{
···
494
// Get updated registration to show
495
registrations, err = db.GetRegistrations(
496
k.Db,
497
-
orm.FilterEq("did", user.Did),
498
orm.FilterEq("domain", domain),
499
)
500
if err != nil {
···
516
}
517
518
func (k *Knots) addMember(w http.ResponseWriter, r *http.Request) {
519
-
user := k.OAuth.GetUser(r)
520
l := k.Logger.With("handler", "addMember")
521
522
domain := chi.URLParam(r, "domain")
···
526
return
527
}
528
l = l.With("domain", domain)
529
-
l = l.With("user", user.Did)
530
531
registrations, err := db.GetRegistrations(
532
k.Db,
533
-
orm.FilterEq("did", user.Did),
534
orm.FilterEq("domain", domain),
535
orm.FilterIsNot("registered", "null"),
536
)
···
583
584
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
585
Collection: tangled.KnotMemberNSID,
586
-
Repo: user.Did,
587
Rkey: rkey,
588
Record: &lexutil.LexiconTypeDecoder{
589
Val: &tangled.KnotMember{
···
618
}
619
620
func (k *Knots) removeMember(w http.ResponseWriter, r *http.Request) {
621
-
user := k.OAuth.GetUser(r)
622
l := k.Logger.With("handler", "removeMember")
623
624
noticeId := "operation-error"
···
634
return
635
}
636
l = l.With("domain", domain)
637
-
l = l.With("user", user.Did)
638
639
registrations, err := db.GetRegistrations(
640
k.Db,
641
-
orm.FilterEq("did", user.Did),
642
orm.FilterEq("domain", domain),
643
orm.FilterIsNot("registered", "null"),
644
)
···
70
}
71
72
func (k *Knots) knots(w http.ResponseWriter, r *http.Request) {
73
+
user := k.OAuth.GetMultiAccountUser(r)
74
registrations, err := db.GetRegistrations(
75
k.Db,
76
+
orm.FilterEq("did", user.Active.Did),
77
)
78
if err != nil {
79
k.Logger.Error("failed to fetch knot registrations", "err", err)
···
92
func (k *Knots) dashboard(w http.ResponseWriter, r *http.Request) {
93
l := k.Logger.With("handler", "dashboard")
94
95
+
user := k.OAuth.GetMultiAccountUser(r)
96
+
l = l.With("user", user.Active.Did)
97
98
domain := chi.URLParam(r, "domain")
99
if domain == "" {
···
103
104
registrations, err := db.GetRegistrations(
105
k.Db,
106
+
orm.FilterEq("did", user.Active.Did),
107
orm.FilterEq("domain", domain),
108
)
109
if err != nil {
···
154
}
155
156
func (k *Knots) register(w http.ResponseWriter, r *http.Request) {
157
+
user := k.OAuth.GetMultiAccountUser(r)
158
l := k.Logger.With("handler", "register")
159
160
noticeId := "register-error"
···
175
return
176
}
177
l = l.With("domain", domain)
178
+
l = l.With("user", user.Active.Did)
179
180
tx, err := k.Db.Begin()
181
if err != nil {
···
188
k.Enforcer.E.LoadPolicy()
189
}()
190
191
+
err = db.AddKnot(tx, domain, user.Active.Did)
192
if err != nil {
193
l.Error("failed to insert", "err", err)
194
fail()
···
210
return
211
}
212
213
+
ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.KnotNSID, user.Active.Did, domain)
214
var exCid *string
215
if ex != nil {
216
exCid = ex.Cid
···
219
// re-announce by registering under same rkey
220
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
221
Collection: tangled.KnotNSID,
222
+
Repo: user.Active.Did,
223
Rkey: domain,
224
Record: &lexutil.LexiconTypeDecoder{
225
Val: &tangled.Knot{
···
250
}
251
252
// begin verification
253
+
err = serververify.RunVerification(r.Context(), domain, user.Active.Did, k.Config.Core.Dev)
254
if err != nil {
255
l.Error("verification failed", "err", err)
256
k.Pages.HxRefresh(w)
257
return
258
}
259
260
+
err = serververify.MarkKnotVerified(k.Db, k.Enforcer, domain, user.Active.Did)
261
if err != nil {
262
l.Error("failed to mark verified", "err", err)
263
k.Pages.HxRefresh(w)
···
275
}
276
277
func (k *Knots) delete(w http.ResponseWriter, r *http.Request) {
278
+
user := k.OAuth.GetMultiAccountUser(r)
279
l := k.Logger.With("handler", "delete")
280
281
noticeId := "operation-error"
···
294
// get record from db first
295
registrations, err := db.GetRegistrations(
296
k.Db,
297
+
orm.FilterEq("did", user.Active.Did),
298
orm.FilterEq("domain", domain),
299
)
300
if err != nil {
···
322
323
err = db.DeleteKnot(
324
tx,
325
+
orm.FilterEq("did", user.Active.Did),
326
orm.FilterEq("domain", domain),
327
)
328
if err != nil {
···
350
351
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
352
Collection: tangled.KnotNSID,
353
+
Repo: user.Active.Did,
354
Rkey: domain,
355
})
356
if err != nil {
···
382
}
383
384
func (k *Knots) retry(w http.ResponseWriter, r *http.Request) {
385
+
user := k.OAuth.GetMultiAccountUser(r)
386
l := k.Logger.With("handler", "retry")
387
388
noticeId := "operation-error"
···
398
return
399
}
400
l = l.With("domain", domain)
401
+
l = l.With("user", user.Active.Did)
402
403
// get record from db first
404
registrations, err := db.GetRegistrations(
405
k.Db,
406
+
orm.FilterEq("did", user.Active.Did),
407
orm.FilterEq("domain", domain),
408
)
409
if err != nil {
···
419
registration := registrations[0]
420
421
// begin verification
422
+
err = serververify.RunVerification(r.Context(), domain, user.Active.Did, k.Config.Core.Dev)
423
if err != nil {
424
l.Error("verification failed", "err", err)
425
···
437
return
438
}
439
440
+
err = serververify.MarkKnotVerified(k.Db, k.Enforcer, domain, user.Active.Did)
441
if err != nil {
442
l.Error("failed to mark verified", "err", err)
443
k.Pages.Notice(w, noticeId, err.Error())
···
456
return
457
}
458
459
+
ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.KnotNSID, user.Active.Did, domain)
460
var exCid *string
461
if ex != nil {
462
exCid = ex.Cid
···
465
// ignore the error here
466
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
467
Collection: tangled.KnotNSID,
468
+
Repo: user.Active.Did,
469
Rkey: domain,
470
Record: &lexutil.LexiconTypeDecoder{
471
Val: &tangled.Knot{
···
494
// Get updated registration to show
495
registrations, err = db.GetRegistrations(
496
k.Db,
497
+
orm.FilterEq("did", user.Active.Did),
498
orm.FilterEq("domain", domain),
499
)
500
if err != nil {
···
516
}
517
518
func (k *Knots) addMember(w http.ResponseWriter, r *http.Request) {
519
+
user := k.OAuth.GetMultiAccountUser(r)
520
l := k.Logger.With("handler", "addMember")
521
522
domain := chi.URLParam(r, "domain")
···
526
return
527
}
528
l = l.With("domain", domain)
529
+
l = l.With("user", user.Active.Did)
530
531
registrations, err := db.GetRegistrations(
532
k.Db,
533
+
orm.FilterEq("did", user.Active.Did),
534
orm.FilterEq("domain", domain),
535
orm.FilterIsNot("registered", "null"),
536
)
···
583
584
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
585
Collection: tangled.KnotMemberNSID,
586
+
Repo: user.Active.Did,
587
Rkey: rkey,
588
Record: &lexutil.LexiconTypeDecoder{
589
Val: &tangled.KnotMember{
···
618
}
619
620
func (k *Knots) removeMember(w http.ResponseWriter, r *http.Request) {
621
+
user := k.OAuth.GetMultiAccountUser(r)
622
l := k.Logger.With("handler", "removeMember")
623
624
noticeId := "operation-error"
···
634
return
635
}
636
l = l.With("domain", domain)
637
+
l = l.With("user", user.Active.Did)
638
639
registrations, err := db.GetRegistrations(
640
k.Db,
641
+
orm.FilterEq("did", user.Active.Did),
642
orm.FilterEq("domain", domain),
643
orm.FilterIsNot("registered", "null"),
644
)
+2
-2
appview/labels/labels.go
+2
-2
appview/labels/labels.go
···
68
// - this handler should calculate the diff in order to create the labelop record
69
// - we need the diff in order to maintain a "history" of operations performed by users
70
func (l *Labels) PerformLabelOp(w http.ResponseWriter, r *http.Request) {
71
-
user := l.oauth.GetUser(r)
72
73
noticeId := "add-label-error"
74
···
82
return
83
}
84
85
-
did := user.Did
86
rkey := tid.TID()
87
performedAt := time.Now()
88
indexedAt := time.Now()
···
68
// - this handler should calculate the diff in order to create the labelop record
69
// - we need the diff in order to maintain a "history" of operations performed by users
70
func (l *Labels) PerformLabelOp(w http.ResponseWriter, r *http.Request) {
71
+
user := l.oauth.GetMultiAccountUser(r)
72
73
noticeId := "add-label-error"
74
···
82
return
83
}
84
85
+
did := user.Active.Did
86
rkey := tid.TID()
87
performedAt := time.Now()
88
indexedAt := time.Now()
+6
-8
appview/middleware/middleware.go
+6
-8
appview/middleware/middleware.go
···
115
return func(next http.Handler) http.Handler {
116
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
117
// requires auth also
118
-
actor := mw.oauth.GetUser(r)
119
if actor == nil {
120
// we need a logged in user
121
log.Printf("not logged in, redirecting")
···
128
return
129
}
130
131
-
ok, err := mw.enforcer.E.HasGroupingPolicy(actor.Did, group, domain)
132
if err != nil || !ok {
133
-
// we need a logged in user
134
-
log.Printf("%s does not have perms of a %s in domain %s", actor.Did, group, domain)
135
http.Error(w, "Forbiden", http.StatusUnauthorized)
136
return
137
}
···
149
return func(next http.Handler) http.Handler {
150
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
151
// requires auth also
152
-
actor := mw.oauth.GetUser(r)
153
if actor == nil {
154
// we need a logged in user
155
log.Printf("not logged in, redirecting")
···
162
return
163
}
164
165
-
ok, err := mw.enforcer.E.Enforce(actor.Did, f.Knot, f.DidSlashRepo(), requiredPerm)
166
if err != nil || !ok {
167
-
// we need a logged in user
168
-
log.Printf("%s does not have perms of a %s in repo %s", actor.Did, requiredPerm, f.DidSlashRepo())
169
http.Error(w, "Forbiden", http.StatusUnauthorized)
170
return
171
}
···
115
return func(next http.Handler) http.Handler {
116
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
117
// requires auth also
118
+
actor := mw.oauth.GetMultiAccountUser(r)
119
if actor == nil {
120
// we need a logged in user
121
log.Printf("not logged in, redirecting")
···
128
return
129
}
130
131
+
ok, err := mw.enforcer.E.HasGroupingPolicy(actor.Active.Did, group, domain)
132
if err != nil || !ok {
133
+
log.Printf("%s does not have perms of a %s in domain %s", actor.Active.Did, group, domain)
134
http.Error(w, "Forbiden", http.StatusUnauthorized)
135
return
136
}
···
148
return func(next http.Handler) http.Handler {
149
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
150
// requires auth also
151
+
actor := mw.oauth.GetMultiAccountUser(r)
152
if actor == nil {
153
// we need a logged in user
154
log.Printf("not logged in, redirecting")
···
161
return
162
}
163
164
+
ok, err := mw.enforcer.E.Enforce(actor.Active.Did, f.Knot, f.DidSlashRepo(), requiredPerm)
165
if err != nil || !ok {
166
+
log.Printf("%s does not have perms of a %s in repo %s", actor.Active.Did, requiredPerm, f.DidSlashRepo())
167
http.Error(w, "Forbiden", http.StatusUnauthorized)
168
return
169
}
+6
-6
appview/notifications/notifications.go
+6
-6
appview/notifications/notifications.go
···
48
49
func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request) {
50
l := n.logger.With("handler", "notificationsPage")
51
-
user := n.oauth.GetUser(r)
52
53
page := pagination.FromContext(r.Context())
54
55
total, err := db.CountNotifications(
56
n.db,
57
-
orm.FilterEq("recipient_did", user.Did),
58
)
59
if err != nil {
60
l.Error("failed to get total notifications", "err", err)
···
65
notifications, err := db.GetNotificationsWithEntities(
66
n.db,
67
page,
68
-
orm.FilterEq("recipient_did", user.Did),
69
)
70
if err != nil {
71
l.Error("failed to get notifications", "err", err)
···
73
return
74
}
75
76
-
err = db.MarkAllNotificationsRead(n.db, user.Did)
77
if err != nil {
78
l.Error("failed to mark notifications as read", "err", err)
79
}
···
90
}
91
92
func (n *Notifications) getUnreadCount(w http.ResponseWriter, r *http.Request) {
93
-
user := n.oauth.GetUser(r)
94
if user == nil {
95
http.Error(w, "Forbidden", http.StatusUnauthorized)
96
return
···
98
99
count, err := db.CountNotifications(
100
n.db,
101
-
orm.FilterEq("recipient_did", user.Did),
102
orm.FilterEq("read", 0),
103
)
104
if err != nil {
···
48
49
func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request) {
50
l := n.logger.With("handler", "notificationsPage")
51
+
user := n.oauth.GetMultiAccountUser(r)
52
53
page := pagination.FromContext(r.Context())
54
55
total, err := db.CountNotifications(
56
n.db,
57
+
orm.FilterEq("recipient_did", user.Active.Did),
58
)
59
if err != nil {
60
l.Error("failed to get total notifications", "err", err)
···
65
notifications, err := db.GetNotificationsWithEntities(
66
n.db,
67
page,
68
+
orm.FilterEq("recipient_did", user.Active.Did),
69
)
70
if err != nil {
71
l.Error("failed to get notifications", "err", err)
···
73
return
74
}
75
76
+
err = db.MarkAllNotificationsRead(n.db, user.Active.Did)
77
if err != nil {
78
l.Error("failed to mark notifications as read", "err", err)
79
}
···
90
}
91
92
func (n *Notifications) getUnreadCount(w http.ResponseWriter, r *http.Request) {
93
+
user := n.oauth.GetMultiAccountUser(r)
94
if user == nil {
95
http.Error(w, "Forbidden", http.StatusUnauthorized)
96
return
···
98
99
count, err := db.CountNotifications(
100
n.db,
101
+
orm.FilterEq("recipient_did", user.Active.Did),
102
orm.FilterEq("read", 0),
103
)
104
if err != nil {
+2
-2
appview/pipelines/pipelines.go
+2
-2
appview/pipelines/pipelines.go
···
77
}
78
79
func (p *Pipelines) Index(w http.ResponseWriter, r *http.Request) {
80
-
user := p.oauth.GetUser(r)
81
l := p.logger.With("handler", "Index")
82
83
f, err := p.repoResolver.Resolve(r)
···
106
}
107
108
func (p *Pipelines) Workflow(w http.ResponseWriter, r *http.Request) {
109
-
user := p.oauth.GetUser(r)
110
l := p.logger.With("handler", "Workflow")
111
112
f, err := p.repoResolver.Resolve(r)
···
77
}
78
79
func (p *Pipelines) Index(w http.ResponseWriter, r *http.Request) {
80
+
user := p.oauth.GetMultiAccountUser(r)
81
l := p.logger.With("handler", "Index")
82
83
f, err := p.repoResolver.Resolve(r)
···
106
}
107
108
func (p *Pipelines) Workflow(w http.ResponseWriter, r *http.Request) {
109
+
user := p.oauth.GetMultiAccountUser(r)
110
l := p.logger.With("handler", "Workflow")
111
112
f, err := p.repoResolver.Resolve(r)
+55
-55
appview/pulls/pulls.go
+55
-55
appview/pulls/pulls.go
···
97
func (s *Pulls) PullActions(w http.ResponseWriter, r *http.Request) {
98
switch r.Method {
99
case http.MethodGet:
100
-
user := s.oauth.GetUser(r)
101
f, err := s.repoResolver.Resolve(r)
102
if err != nil {
103
log.Println("failed to get repo and knot", err)
···
128
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
129
branchDeleteStatus := s.branchDeleteStatus(r, f, pull)
130
resubmitResult := pages.Unknown
131
-
if user.Did == pull.OwnerDid {
132
resubmitResult = s.resubmitCheck(r, f, pull, stack)
133
}
134
···
147
}
148
149
func (s *Pulls) RepoSinglePull(w http.ResponseWriter, r *http.Request) {
150
-
user := s.oauth.GetUser(r)
151
f, err := s.repoResolver.Resolve(r)
152
if err != nil {
153
log.Println("failed to get repo and knot", err)
···
175
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
176
branchDeleteStatus := s.branchDeleteStatus(r, f, pull)
177
resubmitResult := pages.Unknown
178
-
if user != nil && user.Did == pull.OwnerDid {
179
resubmitResult = s.resubmitCheck(r, f, pull, stack)
180
}
181
···
217
218
userReactions := map[models.ReactionKind]bool{}
219
if user != nil {
220
-
userReactions = db.GetReactionStatusMap(s.db, user.Did, pull.AtUri())
221
}
222
223
labelDefs, err := db.GetLabelDefinitions(
···
328
return nil
329
}
330
331
-
user := s.oauth.GetUser(r)
332
if user == nil {
333
return nil
334
}
···
351
}
352
353
// user can only delete branch if they are a collaborator in the repo that the branch belongs to
354
-
perms := s.enforcer.GetPermissionsInRepo(user.Did, repo.Knot, repo.DidSlashRepo())
355
if !slices.Contains(perms, "repo:push") {
356
return nil
357
}
···
438
}
439
440
func (s *Pulls) RepoPullPatch(w http.ResponseWriter, r *http.Request) {
441
-
user := s.oauth.GetUser(r)
442
443
var diffOpts types.DiffOpts
444
if d := r.URL.Query().Get("diff"); d == "split" {
···
479
}
480
481
func (s *Pulls) RepoPullInterdiff(w http.ResponseWriter, r *http.Request) {
482
-
user := s.oauth.GetUser(r)
483
484
var diffOpts types.DiffOpts
485
if d := r.URL.Query().Get("diff"); d == "split" {
···
524
interdiff := patchutil.Interdiff(previousPatch, currentPatch)
525
526
s.pages.RepoPullInterdiffPage(w, pages.RepoPullInterdiffParams{
527
-
LoggedInUser: s.oauth.GetUser(r),
528
RepoInfo: s.repoResolver.GetRepoInfo(r, user),
529
Pull: pull,
530
Round: roundIdInt,
···
556
func (s *Pulls) RepoPulls(w http.ResponseWriter, r *http.Request) {
557
l := s.logger.With("handler", "RepoPulls")
558
559
-
user := s.oauth.GetUser(r)
560
params := r.URL.Query()
561
562
state := models.PullOpen
···
701
}
702
703
s.pages.RepoPulls(w, pages.RepoPullsParams{
704
-
LoggedInUser: s.oauth.GetUser(r),
705
RepoInfo: s.repoResolver.GetRepoInfo(r, user),
706
Pulls: pulls,
707
LabelDefs: defs,
···
715
}
716
717
func (s *Pulls) PullComment(w http.ResponseWriter, r *http.Request) {
718
-
user := s.oauth.GetUser(r)
719
f, err := s.repoResolver.Resolve(r)
720
if err != nil {
721
log.Println("failed to get repo and knot", err)
···
774
}
775
atResp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
776
Collection: tangled.RepoPullCommentNSID,
777
-
Repo: user.Did,
778
Rkey: tid.TID(),
779
Record: &lexutil.LexiconTypeDecoder{
780
Val: &tangled.RepoPullComment{
···
791
}
792
793
comment := &models.PullComment{
794
-
OwnerDid: user.Did,
795
RepoAt: f.RepoAt().String(),
796
PullId: pull.PullId,
797
Body: body,
···
825
}
826
827
func (s *Pulls) NewPull(w http.ResponseWriter, r *http.Request) {
828
-
user := s.oauth.GetUser(r)
829
f, err := s.repoResolver.Resolve(r)
830
if err != nil {
831
log.Println("failed to get repo and knot", err)
···
893
}
894
895
// Determine PR type based on input parameters
896
-
roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo())}
897
isPushAllowed := roles.IsPushAllowed()
898
isBranchBased := isPushAllowed && sourceBranch != "" && fromFork == ""
899
isForkBased := fromFork != "" && sourceBranch != ""
···
993
w http.ResponseWriter,
994
r *http.Request,
995
repo *models.Repo,
996
-
user *oauth.User,
997
title,
998
body,
999
targetBranch,
···
1050
s.createPullRequest(w, r, repo, user, title, body, targetBranch, patch, combined, sourceRev, pullSource, recordPullSource, isStacked)
1051
}
1052
1053
-
func (s *Pulls) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, repo *models.Repo, user *oauth.User, title, body, targetBranch, patch string, isStacked bool) {
1054
if err := s.validator.ValidatePatch(&patch); err != nil {
1055
s.logger.Error("patch validation failed", "err", err)
1056
s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.")
···
1060
s.createPullRequest(w, r, repo, user, title, body, targetBranch, patch, "", "", nil, nil, isStacked)
1061
}
1062
1063
-
func (s *Pulls) handleForkBasedPull(w http.ResponseWriter, r *http.Request, repo *models.Repo, user *oauth.User, forkRepo string, title, body, targetBranch, sourceBranch string, isStacked bool) {
1064
repoString := strings.SplitN(forkRepo, "/", 2)
1065
forkOwnerDid := repoString[0]
1066
repoName := repoString[1]
···
1169
w http.ResponseWriter,
1170
r *http.Request,
1171
repo *models.Repo,
1172
-
user *oauth.User,
1173
title, body, targetBranch string,
1174
patch string,
1175
combined string,
···
1241
Title: title,
1242
Body: body,
1243
TargetBranch: targetBranch,
1244
-
OwnerDid: user.Did,
1245
RepoAt: repo.RepoAt(),
1246
Rkey: rkey,
1247
Mentions: mentions,
···
1273
1274
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
1275
Collection: tangled.RepoPullNSID,
1276
-
Repo: user.Did,
1277
Rkey: rkey,
1278
Record: &lexutil.LexiconTypeDecoder{
1279
Val: &tangled.RepoPull{
···
1310
w http.ResponseWriter,
1311
r *http.Request,
1312
repo *models.Repo,
1313
-
user *oauth.User,
1314
targetBranch string,
1315
patch string,
1316
sourceRev string,
···
1378
})
1379
}
1380
_, err = comatproto.RepoApplyWrites(r.Context(), client, &comatproto.RepoApplyWrites_Input{
1381
-
Repo: user.Did,
1382
Writes: writes,
1383
})
1384
if err != nil {
···
1450
}
1451
1452
func (s *Pulls) PatchUploadFragment(w http.ResponseWriter, r *http.Request) {
1453
-
user := s.oauth.GetUser(r)
1454
1455
s.pages.PullPatchUploadFragment(w, pages.PullPatchUploadParams{
1456
RepoInfo: s.repoResolver.GetRepoInfo(r, user),
···
1458
}
1459
1460
func (s *Pulls) CompareBranchesFragment(w http.ResponseWriter, r *http.Request) {
1461
-
user := s.oauth.GetUser(r)
1462
f, err := s.repoResolver.Resolve(r)
1463
if err != nil {
1464
log.Println("failed to get repo and knot", err)
···
1513
}
1514
1515
func (s *Pulls) CompareForksFragment(w http.ResponseWriter, r *http.Request) {
1516
-
user := s.oauth.GetUser(r)
1517
1518
-
forks, err := db.GetForksByDid(s.db, user.Did)
1519
if err != nil {
1520
log.Println("failed to get forks", err)
1521
return
···
1529
}
1530
1531
func (s *Pulls) CompareForksBranchesFragment(w http.ResponseWriter, r *http.Request) {
1532
-
user := s.oauth.GetUser(r)
1533
1534
f, err := s.repoResolver.Resolve(r)
1535
if err != nil {
···
1622
}
1623
1624
func (s *Pulls) ResubmitPull(w http.ResponseWriter, r *http.Request) {
1625
-
user := s.oauth.GetUser(r)
1626
1627
pull, ok := r.Context().Value("pull").(*models.Pull)
1628
if !ok {
···
1653
}
1654
1655
func (s *Pulls) resubmitPatch(w http.ResponseWriter, r *http.Request) {
1656
-
user := s.oauth.GetUser(r)
1657
1658
pull, ok := r.Context().Value("pull").(*models.Pull)
1659
if !ok {
···
1668
return
1669
}
1670
1671
-
if user.Did != pull.OwnerDid {
1672
log.Println("unauthorized user")
1673
w.WriteHeader(http.StatusUnauthorized)
1674
return
···
1680
}
1681
1682
func (s *Pulls) resubmitBranch(w http.ResponseWriter, r *http.Request) {
1683
-
user := s.oauth.GetUser(r)
1684
1685
pull, ok := r.Context().Value("pull").(*models.Pull)
1686
if !ok {
···
1695
return
1696
}
1697
1698
-
if user.Did != pull.OwnerDid {
1699
log.Println("unauthorized user")
1700
w.WriteHeader(http.StatusUnauthorized)
1701
return
1702
}
1703
1704
-
roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo())}
1705
if !roles.IsPushAllowed() {
1706
log.Println("unauthorized user")
1707
w.WriteHeader(http.StatusUnauthorized)
···
1745
}
1746
1747
func (s *Pulls) resubmitFork(w http.ResponseWriter, r *http.Request) {
1748
-
user := s.oauth.GetUser(r)
1749
1750
pull, ok := r.Context().Value("pull").(*models.Pull)
1751
if !ok {
···
1760
return
1761
}
1762
1763
-
if user.Did != pull.OwnerDid {
1764
log.Println("unauthorized user")
1765
w.WriteHeader(http.StatusUnauthorized)
1766
return
···
1845
w http.ResponseWriter,
1846
r *http.Request,
1847
repo *models.Repo,
1848
-
user *oauth.User,
1849
pull *models.Pull,
1850
patch string,
1851
combined string,
···
1901
return
1902
}
1903
1904
-
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, pull.Rkey)
1905
if err != nil {
1906
// failed to get record
1907
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
···
1920
1921
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
1922
Collection: tangled.RepoPullNSID,
1923
-
Repo: user.Did,
1924
Rkey: pull.Rkey,
1925
SwapRecord: ex.Cid,
1926
Record: &lexutil.LexiconTypeDecoder{
···
1947
w http.ResponseWriter,
1948
r *http.Request,
1949
repo *models.Repo,
1950
-
user *oauth.User,
1951
pull *models.Pull,
1952
patch string,
1953
stackId string,
···
2137
}
2138
2139
_, err = comatproto.RepoApplyWrites(r.Context(), client, &comatproto.RepoApplyWrites_Input{
2140
-
Repo: user.Did,
2141
Writes: writes,
2142
})
2143
if err != nil {
···
2151
}
2152
2153
func (s *Pulls) MergePull(w http.ResponseWriter, r *http.Request) {
2154
-
user := s.oauth.GetUser(r)
2155
f, err := s.repoResolver.Resolve(r)
2156
if err != nil {
2157
log.Println("failed to resolve repo:", err)
···
2262
2263
// notify about the pull merge
2264
for _, p := range pullsToMerge {
2265
-
s.notifier.NewPullState(r.Context(), syntax.DID(user.Did), p)
2266
}
2267
2268
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
···
2270
}
2271
2272
func (s *Pulls) ClosePull(w http.ResponseWriter, r *http.Request) {
2273
-
user := s.oauth.GetUser(r)
2274
2275
f, err := s.repoResolver.Resolve(r)
2276
if err != nil {
···
2286
}
2287
2288
// auth filter: only owner or collaborators can close
2289
-
roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo())}
2290
isOwner := roles.IsOwner()
2291
isCollaborator := roles.IsCollaborator()
2292
-
isPullAuthor := user.Did == pull.OwnerDid
2293
isCloseAllowed := isOwner || isCollaborator || isPullAuthor
2294
if !isCloseAllowed {
2295
log.Println("failed to close pull")
···
2335
}
2336
2337
for _, p := range pullsToClose {
2338
-
s.notifier.NewPullState(r.Context(), syntax.DID(user.Did), p)
2339
}
2340
2341
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
···
2343
}
2344
2345
func (s *Pulls) ReopenPull(w http.ResponseWriter, r *http.Request) {
2346
-
user := s.oauth.GetUser(r)
2347
2348
f, err := s.repoResolver.Resolve(r)
2349
if err != nil {
···
2360
}
2361
2362
// auth filter: only owner or collaborators can close
2363
-
roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo())}
2364
isOwner := roles.IsOwner()
2365
isCollaborator := roles.IsCollaborator()
2366
-
isPullAuthor := user.Did == pull.OwnerDid
2367
isCloseAllowed := isOwner || isCollaborator || isPullAuthor
2368
if !isCloseAllowed {
2369
log.Println("failed to close pull")
···
2409
}
2410
2411
for _, p := range pullsToReopen {
2412
-
s.notifier.NewPullState(r.Context(), syntax.DID(user.Did), p)
2413
}
2414
2415
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
2416
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pull.PullId))
2417
}
2418
2419
-
func (s *Pulls) newStack(ctx context.Context, repo *models.Repo, user *oauth.User, targetBranch, patch string, pullSource *models.PullSource, stackId string) (models.Stack, error) {
2420
formatPatches, err := patchutil.ExtractPatches(patch)
2421
if err != nil {
2422
return nil, fmt.Errorf("Failed to extract patches: %v", err)
···
2452
Title: title,
2453
Body: body,
2454
TargetBranch: targetBranch,
2455
-
OwnerDid: user.Did,
2456
RepoAt: repo.RepoAt(),
2457
Rkey: rkey,
2458
Mentions: mentions,
···
97
func (s *Pulls) PullActions(w http.ResponseWriter, r *http.Request) {
98
switch r.Method {
99
case http.MethodGet:
100
+
user := s.oauth.GetMultiAccountUser(r)
101
f, err := s.repoResolver.Resolve(r)
102
if err != nil {
103
log.Println("failed to get repo and knot", err)
···
128
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
129
branchDeleteStatus := s.branchDeleteStatus(r, f, pull)
130
resubmitResult := pages.Unknown
131
+
if user.Active.Did == pull.OwnerDid {
132
resubmitResult = s.resubmitCheck(r, f, pull, stack)
133
}
134
···
147
}
148
149
func (s *Pulls) RepoSinglePull(w http.ResponseWriter, r *http.Request) {
150
+
user := s.oauth.GetMultiAccountUser(r)
151
f, err := s.repoResolver.Resolve(r)
152
if err != nil {
153
log.Println("failed to get repo and knot", err)
···
175
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
176
branchDeleteStatus := s.branchDeleteStatus(r, f, pull)
177
resubmitResult := pages.Unknown
178
+
if user != nil && user.Active != nil && user.Active.Did == pull.OwnerDid {
179
resubmitResult = s.resubmitCheck(r, f, pull, stack)
180
}
181
···
217
218
userReactions := map[models.ReactionKind]bool{}
219
if user != nil {
220
+
userReactions = db.GetReactionStatusMap(s.db, user.Active.Did, pull.AtUri())
221
}
222
223
labelDefs, err := db.GetLabelDefinitions(
···
328
return nil
329
}
330
331
+
user := s.oauth.GetMultiAccountUser(r)
332
if user == nil {
333
return nil
334
}
···
351
}
352
353
// user can only delete branch if they are a collaborator in the repo that the branch belongs to
354
+
perms := s.enforcer.GetPermissionsInRepo(user.Active.Did, repo.Knot, repo.DidSlashRepo())
355
if !slices.Contains(perms, "repo:push") {
356
return nil
357
}
···
438
}
439
440
func (s *Pulls) RepoPullPatch(w http.ResponseWriter, r *http.Request) {
441
+
user := s.oauth.GetMultiAccountUser(r)
442
443
var diffOpts types.DiffOpts
444
if d := r.URL.Query().Get("diff"); d == "split" {
···
479
}
480
481
func (s *Pulls) RepoPullInterdiff(w http.ResponseWriter, r *http.Request) {
482
+
user := s.oauth.GetMultiAccountUser(r)
483
484
var diffOpts types.DiffOpts
485
if d := r.URL.Query().Get("diff"); d == "split" {
···
524
interdiff := patchutil.Interdiff(previousPatch, currentPatch)
525
526
s.pages.RepoPullInterdiffPage(w, pages.RepoPullInterdiffParams{
527
+
LoggedInUser: s.oauth.GetMultiAccountUser(r),
528
RepoInfo: s.repoResolver.GetRepoInfo(r, user),
529
Pull: pull,
530
Round: roundIdInt,
···
556
func (s *Pulls) RepoPulls(w http.ResponseWriter, r *http.Request) {
557
l := s.logger.With("handler", "RepoPulls")
558
559
+
user := s.oauth.GetMultiAccountUser(r)
560
params := r.URL.Query()
561
562
state := models.PullOpen
···
701
}
702
703
s.pages.RepoPulls(w, pages.RepoPullsParams{
704
+
LoggedInUser: s.oauth.GetMultiAccountUser(r),
705
RepoInfo: s.repoResolver.GetRepoInfo(r, user),
706
Pulls: pulls,
707
LabelDefs: defs,
···
715
}
716
717
func (s *Pulls) PullComment(w http.ResponseWriter, r *http.Request) {
718
+
user := s.oauth.GetMultiAccountUser(r)
719
f, err := s.repoResolver.Resolve(r)
720
if err != nil {
721
log.Println("failed to get repo and knot", err)
···
774
}
775
atResp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
776
Collection: tangled.RepoPullCommentNSID,
777
+
Repo: user.Active.Did,
778
Rkey: tid.TID(),
779
Record: &lexutil.LexiconTypeDecoder{
780
Val: &tangled.RepoPullComment{
···
791
}
792
793
comment := &models.PullComment{
794
+
OwnerDid: user.Active.Did,
795
RepoAt: f.RepoAt().String(),
796
PullId: pull.PullId,
797
Body: body,
···
825
}
826
827
func (s *Pulls) NewPull(w http.ResponseWriter, r *http.Request) {
828
+
user := s.oauth.GetMultiAccountUser(r)
829
f, err := s.repoResolver.Resolve(r)
830
if err != nil {
831
log.Println("failed to get repo and knot", err)
···
893
}
894
895
// Determine PR type based on input parameters
896
+
roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(user.Active.Did, f.Knot, f.DidSlashRepo())}
897
isPushAllowed := roles.IsPushAllowed()
898
isBranchBased := isPushAllowed && sourceBranch != "" && fromFork == ""
899
isForkBased := fromFork != "" && sourceBranch != ""
···
993
w http.ResponseWriter,
994
r *http.Request,
995
repo *models.Repo,
996
+
user *oauth.MultiAccountUser,
997
title,
998
body,
999
targetBranch,
···
1050
s.createPullRequest(w, r, repo, user, title, body, targetBranch, patch, combined, sourceRev, pullSource, recordPullSource, isStacked)
1051
}
1052
1053
+
func (s *Pulls) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, repo *models.Repo, user *oauth.MultiAccountUser, title, body, targetBranch, patch string, isStacked bool) {
1054
if err := s.validator.ValidatePatch(&patch); err != nil {
1055
s.logger.Error("patch validation failed", "err", err)
1056
s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.")
···
1060
s.createPullRequest(w, r, repo, user, title, body, targetBranch, patch, "", "", nil, nil, isStacked)
1061
}
1062
1063
+
func (s *Pulls) handleForkBasedPull(w http.ResponseWriter, r *http.Request, repo *models.Repo, user *oauth.MultiAccountUser, forkRepo string, title, body, targetBranch, sourceBranch string, isStacked bool) {
1064
repoString := strings.SplitN(forkRepo, "/", 2)
1065
forkOwnerDid := repoString[0]
1066
repoName := repoString[1]
···
1169
w http.ResponseWriter,
1170
r *http.Request,
1171
repo *models.Repo,
1172
+
user *oauth.MultiAccountUser,
1173
title, body, targetBranch string,
1174
patch string,
1175
combined string,
···
1241
Title: title,
1242
Body: body,
1243
TargetBranch: targetBranch,
1244
+
OwnerDid: user.Active.Did,
1245
RepoAt: repo.RepoAt(),
1246
Rkey: rkey,
1247
Mentions: mentions,
···
1273
1274
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
1275
Collection: tangled.RepoPullNSID,
1276
+
Repo: user.Active.Did,
1277
Rkey: rkey,
1278
Record: &lexutil.LexiconTypeDecoder{
1279
Val: &tangled.RepoPull{
···
1310
w http.ResponseWriter,
1311
r *http.Request,
1312
repo *models.Repo,
1313
+
user *oauth.MultiAccountUser,
1314
targetBranch string,
1315
patch string,
1316
sourceRev string,
···
1378
})
1379
}
1380
_, err = comatproto.RepoApplyWrites(r.Context(), client, &comatproto.RepoApplyWrites_Input{
1381
+
Repo: user.Active.Did,
1382
Writes: writes,
1383
})
1384
if err != nil {
···
1450
}
1451
1452
func (s *Pulls) PatchUploadFragment(w http.ResponseWriter, r *http.Request) {
1453
+
user := s.oauth.GetMultiAccountUser(r)
1454
1455
s.pages.PullPatchUploadFragment(w, pages.PullPatchUploadParams{
1456
RepoInfo: s.repoResolver.GetRepoInfo(r, user),
···
1458
}
1459
1460
func (s *Pulls) CompareBranchesFragment(w http.ResponseWriter, r *http.Request) {
1461
+
user := s.oauth.GetMultiAccountUser(r)
1462
f, err := s.repoResolver.Resolve(r)
1463
if err != nil {
1464
log.Println("failed to get repo and knot", err)
···
1513
}
1514
1515
func (s *Pulls) CompareForksFragment(w http.ResponseWriter, r *http.Request) {
1516
+
user := s.oauth.GetMultiAccountUser(r)
1517
1518
+
forks, err := db.GetForksByDid(s.db, user.Active.Did)
1519
if err != nil {
1520
log.Println("failed to get forks", err)
1521
return
···
1529
}
1530
1531
func (s *Pulls) CompareForksBranchesFragment(w http.ResponseWriter, r *http.Request) {
1532
+
user := s.oauth.GetMultiAccountUser(r)
1533
1534
f, err := s.repoResolver.Resolve(r)
1535
if err != nil {
···
1622
}
1623
1624
func (s *Pulls) ResubmitPull(w http.ResponseWriter, r *http.Request) {
1625
+
user := s.oauth.GetMultiAccountUser(r)
1626
1627
pull, ok := r.Context().Value("pull").(*models.Pull)
1628
if !ok {
···
1653
}
1654
1655
func (s *Pulls) resubmitPatch(w http.ResponseWriter, r *http.Request) {
1656
+
user := s.oauth.GetMultiAccountUser(r)
1657
1658
pull, ok := r.Context().Value("pull").(*models.Pull)
1659
if !ok {
···
1668
return
1669
}
1670
1671
+
if user.Active.Did != pull.OwnerDid {
1672
log.Println("unauthorized user")
1673
w.WriteHeader(http.StatusUnauthorized)
1674
return
···
1680
}
1681
1682
func (s *Pulls) resubmitBranch(w http.ResponseWriter, r *http.Request) {
1683
+
user := s.oauth.GetMultiAccountUser(r)
1684
1685
pull, ok := r.Context().Value("pull").(*models.Pull)
1686
if !ok {
···
1695
return
1696
}
1697
1698
+
if user.Active.Did != pull.OwnerDid {
1699
log.Println("unauthorized user")
1700
w.WriteHeader(http.StatusUnauthorized)
1701
return
1702
}
1703
1704
+
roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(user.Active.Did, f.Knot, f.DidSlashRepo())}
1705
if !roles.IsPushAllowed() {
1706
log.Println("unauthorized user")
1707
w.WriteHeader(http.StatusUnauthorized)
···
1745
}
1746
1747
func (s *Pulls) resubmitFork(w http.ResponseWriter, r *http.Request) {
1748
+
user := s.oauth.GetMultiAccountUser(r)
1749
1750
pull, ok := r.Context().Value("pull").(*models.Pull)
1751
if !ok {
···
1760
return
1761
}
1762
1763
+
if user.Active.Did != pull.OwnerDid {
1764
log.Println("unauthorized user")
1765
w.WriteHeader(http.StatusUnauthorized)
1766
return
···
1845
w http.ResponseWriter,
1846
r *http.Request,
1847
repo *models.Repo,
1848
+
user *oauth.MultiAccountUser,
1849
pull *models.Pull,
1850
patch string,
1851
combined string,
···
1901
return
1902
}
1903
1904
+
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Active.Did, pull.Rkey)
1905
if err != nil {
1906
// failed to get record
1907
s.pages.Notice(w, "resubmit-error", "Failed to update pull, no record found on PDS.")
···
1920
1921
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
1922
Collection: tangled.RepoPullNSID,
1923
+
Repo: user.Active.Did,
1924
Rkey: pull.Rkey,
1925
SwapRecord: ex.Cid,
1926
Record: &lexutil.LexiconTypeDecoder{
···
1947
w http.ResponseWriter,
1948
r *http.Request,
1949
repo *models.Repo,
1950
+
user *oauth.MultiAccountUser,
1951
pull *models.Pull,
1952
patch string,
1953
stackId string,
···
2137
}
2138
2139
_, err = comatproto.RepoApplyWrites(r.Context(), client, &comatproto.RepoApplyWrites_Input{
2140
+
Repo: user.Active.Did,
2141
Writes: writes,
2142
})
2143
if err != nil {
···
2151
}
2152
2153
func (s *Pulls) MergePull(w http.ResponseWriter, r *http.Request) {
2154
+
user := s.oauth.GetMultiAccountUser(r)
2155
f, err := s.repoResolver.Resolve(r)
2156
if err != nil {
2157
log.Println("failed to resolve repo:", err)
···
2262
2263
// notify about the pull merge
2264
for _, p := range pullsToMerge {
2265
+
s.notifier.NewPullState(r.Context(), syntax.DID(user.Active.Did), p)
2266
}
2267
2268
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
···
2270
}
2271
2272
func (s *Pulls) ClosePull(w http.ResponseWriter, r *http.Request) {
2273
+
user := s.oauth.GetMultiAccountUser(r)
2274
2275
f, err := s.repoResolver.Resolve(r)
2276
if err != nil {
···
2286
}
2287
2288
// auth filter: only owner or collaborators can close
2289
+
roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(user.Active.Did, f.Knot, f.DidSlashRepo())}
2290
isOwner := roles.IsOwner()
2291
isCollaborator := roles.IsCollaborator()
2292
+
isPullAuthor := user.Active.Did == pull.OwnerDid
2293
isCloseAllowed := isOwner || isCollaborator || isPullAuthor
2294
if !isCloseAllowed {
2295
log.Println("failed to close pull")
···
2335
}
2336
2337
for _, p := range pullsToClose {
2338
+
s.notifier.NewPullState(r.Context(), syntax.DID(user.Active.Did), p)
2339
}
2340
2341
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
···
2343
}
2344
2345
func (s *Pulls) ReopenPull(w http.ResponseWriter, r *http.Request) {
2346
+
user := s.oauth.GetMultiAccountUser(r)
2347
2348
f, err := s.repoResolver.Resolve(r)
2349
if err != nil {
···
2360
}
2361
2362
// auth filter: only owner or collaborators can close
2363
+
roles := repoinfo.RolesInRepo{Roles: s.enforcer.GetPermissionsInRepo(user.Active.Did, f.Knot, f.DidSlashRepo())}
2364
isOwner := roles.IsOwner()
2365
isCollaborator := roles.IsCollaborator()
2366
+
isPullAuthor := user.Active.Did == pull.OwnerDid
2367
isCloseAllowed := isOwner || isCollaborator || isPullAuthor
2368
if !isCloseAllowed {
2369
log.Println("failed to close pull")
···
2409
}
2410
2411
for _, p := range pullsToReopen {
2412
+
s.notifier.NewPullState(r.Context(), syntax.DID(user.Active.Did), p)
2413
}
2414
2415
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
2416
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pull.PullId))
2417
}
2418
2419
+
func (s *Pulls) newStack(ctx context.Context, repo *models.Repo, user *oauth.MultiAccountUser, targetBranch, patch string, pullSource *models.PullSource, stackId string) (models.Stack, error) {
2420
formatPatches, err := patchutil.ExtractPatches(patch)
2421
if err != nil {
2422
return nil, fmt.Errorf("Failed to extract patches: %v", err)
···
2452
Title: title,
2453
Body: body,
2454
TargetBranch: targetBranch,
2455
+
OwnerDid: user.Active.Did,
2456
RepoAt: repo.RepoAt(),
2457
Rkey: rkey,
2458
Mentions: mentions,
+6
-6
appview/repo/artifact.go
+6
-6
appview/repo/artifact.go
···
30
31
// TODO: proper statuses here on early exit
32
func (rp *Repo) AttachArtifact(w http.ResponseWriter, r *http.Request) {
33
-
user := rp.oauth.GetUser(r)
34
tagParam := chi.URLParam(r, "tag")
35
f, err := rp.repoResolver.Resolve(r)
36
if err != nil {
···
75
76
putRecordResp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
77
Collection: tangled.RepoArtifactNSID,
78
-
Repo: user.Did,
79
Rkey: rkey,
80
Record: &lexutil.LexiconTypeDecoder{
81
Val: &tangled.RepoArtifact{
···
104
defer tx.Rollback()
105
106
artifact := models.Artifact{
107
-
Did: user.Did,
108
Rkey: rkey,
109
RepoAt: f.RepoAt(),
110
Tag: tag.Tag.Hash,
···
220
221
// TODO: proper statuses here on early exit
222
func (rp *Repo) DeleteArtifact(w http.ResponseWriter, r *http.Request) {
223
-
user := rp.oauth.GetUser(r)
224
tagParam := chi.URLParam(r, "tag")
225
filename := chi.URLParam(r, "file")
226
f, err := rp.repoResolver.Resolve(r)
···
251
252
artifact := artifacts[0]
253
254
-
if user.Did != artifact.Did {
255
log.Println("user not authorized to delete artifact", err)
256
rp.pages.Notice(w, "remove", "Unauthorized deletion of artifact.")
257
return
···
259
260
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
261
Collection: tangled.RepoArtifactNSID,
262
-
Repo: user.Did,
263
Rkey: artifact.Rkey,
264
})
265
if err != nil {
···
30
31
// TODO: proper statuses here on early exit
32
func (rp *Repo) AttachArtifact(w http.ResponseWriter, r *http.Request) {
33
+
user := rp.oauth.GetMultiAccountUser(r)
34
tagParam := chi.URLParam(r, "tag")
35
f, err := rp.repoResolver.Resolve(r)
36
if err != nil {
···
75
76
putRecordResp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
77
Collection: tangled.RepoArtifactNSID,
78
+
Repo: user.Active.Did,
79
Rkey: rkey,
80
Record: &lexutil.LexiconTypeDecoder{
81
Val: &tangled.RepoArtifact{
···
104
defer tx.Rollback()
105
106
artifact := models.Artifact{
107
+
Did: user.Active.Did,
108
Rkey: rkey,
109
RepoAt: f.RepoAt(),
110
Tag: tag.Tag.Hash,
···
220
221
// TODO: proper statuses here on early exit
222
func (rp *Repo) DeleteArtifact(w http.ResponseWriter, r *http.Request) {
223
+
user := rp.oauth.GetMultiAccountUser(r)
224
tagParam := chi.URLParam(r, "tag")
225
filename := chi.URLParam(r, "file")
226
f, err := rp.repoResolver.Resolve(r)
···
251
252
artifact := artifacts[0]
253
254
+
if user.Active.Did != artifact.Did {
255
log.Println("user not authorized to delete artifact", err)
256
rp.pages.Notice(w, "remove", "Unauthorized deletion of artifact.")
257
return
···
259
260
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
261
Collection: tangled.RepoArtifactNSID,
262
+
Repo: user.Active.Did,
263
Rkey: artifact.Rkey,
264
})
265
if err != nil {
+1
-1
appview/repo/blob.go
+1
-1
appview/repo/blob.go
+1
-1
appview/repo/branches.go
+1
-1
appview/repo/branches.go
+2
-2
appview/repo/compare.go
+2
-2
appview/repo/compare.go
···
20
func (rp *Repo) CompareNew(w http.ResponseWriter, r *http.Request) {
21
l := rp.logger.With("handler", "RepoCompareNew")
22
23
-
user := rp.oauth.GetUser(r)
24
f, err := rp.repoResolver.Resolve(r)
25
if err != nil {
26
l.Error("failed to get repo and knot", "err", err)
···
101
func (rp *Repo) Compare(w http.ResponseWriter, r *http.Request) {
102
l := rp.logger.With("handler", "RepoCompare")
103
104
-
user := rp.oauth.GetUser(r)
105
f, err := rp.repoResolver.Resolve(r)
106
if err != nil {
107
l.Error("failed to get repo and knot", "err", err)
···
20
func (rp *Repo) CompareNew(w http.ResponseWriter, r *http.Request) {
21
l := rp.logger.With("handler", "RepoCompareNew")
22
23
+
user := rp.oauth.GetMultiAccountUser(r)
24
f, err := rp.repoResolver.Resolve(r)
25
if err != nil {
26
l.Error("failed to get repo and knot", "err", err)
···
101
func (rp *Repo) Compare(w http.ResponseWriter, r *http.Request) {
102
l := rp.logger.With("handler", "RepoCompare")
103
104
+
user := rp.oauth.GetMultiAccountUser(r)
105
f, err := rp.repoResolver.Resolve(r)
106
if err != nil {
107
l.Error("failed to get repo and knot", "err", err)
+1
-1
appview/repo/index.go
+1
-1
appview/repo/index.go
+2
-2
appview/repo/log.go
+2
-2
appview/repo/log.go
···
109
}
110
}
111
112
-
user := rp.oauth.GetUser(r)
113
114
emailToDidMap, err := db.GetEmailToDid(rp.db, uniqueEmails(xrpcResp.Commits), true)
115
if err != nil {
···
197
l.Error("failed to GetVerifiedCommits", "err", err)
198
}
199
200
-
user := rp.oauth.GetUser(r)
201
pipelines, err := getPipelineStatuses(rp.db, f, []string{result.Diff.Commit.This})
202
if err != nil {
203
l.Error("failed to getPipelineStatuses", "err", err)
···
109
}
110
}
111
112
+
user := rp.oauth.GetMultiAccountUser(r)
113
114
emailToDidMap, err := db.GetEmailToDid(rp.db, uniqueEmails(xrpcResp.Commits), true)
115
if err != nil {
···
197
l.Error("failed to GetVerifiedCommits", "err", err)
198
}
199
200
+
user := rp.oauth.GetMultiAccountUser(r)
201
pipelines, err := getPipelineStatuses(rp.db, f, []string{result.Diff.Commit.This})
202
if err != nil {
203
l.Error("failed to getPipelineStatuses", "err", err)
+34
-34
appview/repo/repo.go
+34
-34
appview/repo/repo.go
···
81
82
// modify the spindle configured for this repo
83
func (rp *Repo) EditSpindle(w http.ResponseWriter, r *http.Request) {
84
-
user := rp.oauth.GetUser(r)
85
l := rp.logger.With("handler", "EditSpindle")
86
-
l = l.With("did", user.Did)
87
88
errorId := "operation-error"
89
fail := func(msg string, err error) {
···
107
108
if !removingSpindle {
109
// ensure that this is a valid spindle for this user
110
-
validSpindles, err := rp.enforcer.GetSpindlesForUser(user.Did)
111
if err != nil {
112
fail("Failed to find spindles. Try again later.", err)
113
return
···
168
}
169
170
func (rp *Repo) AddLabelDef(w http.ResponseWriter, r *http.Request) {
171
-
user := rp.oauth.GetUser(r)
172
l := rp.logger.With("handler", "AddLabel")
173
-
l = l.With("did", user.Did)
174
175
f, err := rp.repoResolver.Resolve(r)
176
if err != nil {
···
216
}
217
218
label := models.LabelDefinition{
219
-
Did: user.Did,
220
Rkey: tid.TID(),
221
Name: name,
222
ValueType: valueType,
···
327
}
328
329
func (rp *Repo) DeleteLabelDef(w http.ResponseWriter, r *http.Request) {
330
-
user := rp.oauth.GetUser(r)
331
l := rp.logger.With("handler", "DeleteLabel")
332
-
l = l.With("did", user.Did)
333
334
f, err := rp.repoResolver.Resolve(r)
335
if err != nil {
···
435
}
436
437
func (rp *Repo) SubscribeLabel(w http.ResponseWriter, r *http.Request) {
438
-
user := rp.oauth.GetUser(r)
439
l := rp.logger.With("handler", "SubscribeLabel")
440
-
l = l.With("did", user.Did)
441
442
f, err := rp.repoResolver.Resolve(r)
443
if err != nil {
···
521
}
522
523
func (rp *Repo) UnsubscribeLabel(w http.ResponseWriter, r *http.Request) {
524
-
user := rp.oauth.GetUser(r)
525
l := rp.logger.With("handler", "UnsubscribeLabel")
526
-
l = l.With("did", user.Did)
527
528
f, err := rp.repoResolver.Resolve(r)
529
if err != nil {
···
633
}
634
state := states[subject]
635
636
-
user := rp.oauth.GetUser(r)
637
rp.pages.LabelPanel(w, pages.LabelPanelParams{
638
LoggedInUser: user,
639
RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
···
681
}
682
state := states[subject]
683
684
-
user := rp.oauth.GetUser(r)
685
rp.pages.EditLabelPanel(w, pages.EditLabelPanelParams{
686
LoggedInUser: user,
687
RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
···
692
}
693
694
func (rp *Repo) AddCollaborator(w http.ResponseWriter, r *http.Request) {
695
-
user := rp.oauth.GetUser(r)
696
l := rp.logger.With("handler", "AddCollaborator")
697
-
l = l.With("did", user.Did)
698
699
f, err := rp.repoResolver.Resolve(r)
700
if err != nil {
···
723
return
724
}
725
726
-
if collaboratorIdent.DID.String() == user.Did {
727
fail("You seem to be adding yourself as a collaborator.", nil)
728
return
729
}
···
738
}
739
740
// emit a record
741
-
currentUser := rp.oauth.GetUser(r)
742
rkey := tid.TID()
743
createdAt := time.Now()
744
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
745
Collection: tangled.RepoCollaboratorNSID,
746
-
Repo: currentUser.Did,
747
Rkey: rkey,
748
Record: &lexutil.LexiconTypeDecoder{
749
Val: &tangled.RepoCollaborator{
···
792
}
793
794
err = db.AddCollaborator(tx, models.Collaborator{
795
-
Did: syntax.DID(currentUser.Did),
796
Rkey: rkey,
797
SubjectDid: collaboratorIdent.DID,
798
RepoAt: f.RepoAt(),
···
822
}
823
824
func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) {
825
-
user := rp.oauth.GetUser(r)
826
l := rp.logger.With("handler", "DeleteRepo")
827
828
noticeId := "operation-error"
···
840
}
841
_, err = comatproto.RepoDeleteRecord(r.Context(), atpClient, &comatproto.RepoDeleteRecord_Input{
842
Collection: tangled.RepoNSID,
843
-
Repo: user.Did,
844
Rkey: f.Rkey,
845
})
846
if err != nil {
···
940
ref := chi.URLParam(r, "ref")
941
ref, _ = url.PathUnescape(ref)
942
943
-
user := rp.oauth.GetUser(r)
944
f, err := rp.repoResolver.Resolve(r)
945
if err != nil {
946
l.Error("failed to resolve source repo", "err", err)
···
969
r.Context(),
970
client,
971
&tangled.RepoForkSync_Input{
972
-
Did: user.Did,
973
Name: f.Name,
974
Source: f.Source,
975
Branch: ref,
···
988
func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) {
989
l := rp.logger.With("handler", "ForkRepo")
990
991
-
user := rp.oauth.GetUser(r)
992
f, err := rp.repoResolver.Resolve(r)
993
if err != nil {
994
l.Error("failed to resolve source repo", "err", err)
···
997
998
switch r.Method {
999
case http.MethodGet:
1000
-
user := rp.oauth.GetUser(r)
1001
-
knots, err := rp.enforcer.GetKnotsForUser(user.Did)
1002
if err != nil {
1003
rp.pages.Notice(w, "repo", "Invalid user account.")
1004
return
···
1020
}
1021
l = l.With("targetKnot", targetKnot)
1022
1023
-
ok, err := rp.enforcer.E.Enforce(user.Did, targetKnot, targetKnot, "repo:create")
1024
if err != nil || !ok {
1025
rp.pages.Notice(w, "repo", "You do not have permission to create a repo in this knot.")
1026
return
···
1037
// in the user's account.
1038
existingRepo, err := db.GetRepo(
1039
rp.db,
1040
-
orm.FilterEq("did", user.Did),
1041
orm.FilterEq("name", forkName),
1042
)
1043
if err != nil {
···
1066
// create an atproto record for this fork
1067
rkey := tid.TID()
1068
repo := &models.Repo{
1069
-
Did: user.Did,
1070
Name: forkName,
1071
Knot: targetKnot,
1072
Rkey: rkey,
···
1086
1087
atresp, err := comatproto.RepoPutRecord(r.Context(), atpClient, &comatproto.RepoPutRecord_Input{
1088
Collection: tangled.RepoNSID,
1089
-
Repo: user.Did,
1090
Rkey: rkey,
1091
Record: &lexutil.LexiconTypeDecoder{
1092
Val: &record,
···
1165
}
1166
1167
// acls
1168
-
p, _ := securejoin.SecureJoin(user.Did, forkName)
1169
-
err = rp.enforcer.AddRepo(user.Did, targetKnot, p)
1170
if err != nil {
1171
l.Error("failed to add ACLs", "err", err)
1172
rp.pages.Notice(w, "repo", "Failed to set up repository permissions.")
···
1191
aturi = ""
1192
1193
rp.notifier.NewRepo(r.Context(), repo)
1194
-
rp.pages.HxLocation(w, fmt.Sprintf("/%s/%s", user.Did, forkName))
1195
}
1196
}
1197
···
81
82
// modify the spindle configured for this repo
83
func (rp *Repo) EditSpindle(w http.ResponseWriter, r *http.Request) {
84
+
user := rp.oauth.GetMultiAccountUser(r)
85
l := rp.logger.With("handler", "EditSpindle")
86
+
l = l.With("did", user.Active.Did)
87
88
errorId := "operation-error"
89
fail := func(msg string, err error) {
···
107
108
if !removingSpindle {
109
// ensure that this is a valid spindle for this user
110
+
validSpindles, err := rp.enforcer.GetSpindlesForUser(user.Active.Did)
111
if err != nil {
112
fail("Failed to find spindles. Try again later.", err)
113
return
···
168
}
169
170
func (rp *Repo) AddLabelDef(w http.ResponseWriter, r *http.Request) {
171
+
user := rp.oauth.GetMultiAccountUser(r)
172
l := rp.logger.With("handler", "AddLabel")
173
+
l = l.With("did", user.Active.Did)
174
175
f, err := rp.repoResolver.Resolve(r)
176
if err != nil {
···
216
}
217
218
label := models.LabelDefinition{
219
+
Did: user.Active.Did,
220
Rkey: tid.TID(),
221
Name: name,
222
ValueType: valueType,
···
327
}
328
329
func (rp *Repo) DeleteLabelDef(w http.ResponseWriter, r *http.Request) {
330
+
user := rp.oauth.GetMultiAccountUser(r)
331
l := rp.logger.With("handler", "DeleteLabel")
332
+
l = l.With("did", user.Active.Did)
333
334
f, err := rp.repoResolver.Resolve(r)
335
if err != nil {
···
435
}
436
437
func (rp *Repo) SubscribeLabel(w http.ResponseWriter, r *http.Request) {
438
+
user := rp.oauth.GetMultiAccountUser(r)
439
l := rp.logger.With("handler", "SubscribeLabel")
440
+
l = l.With("did", user.Active.Did)
441
442
f, err := rp.repoResolver.Resolve(r)
443
if err != nil {
···
521
}
522
523
func (rp *Repo) UnsubscribeLabel(w http.ResponseWriter, r *http.Request) {
524
+
user := rp.oauth.GetMultiAccountUser(r)
525
l := rp.logger.With("handler", "UnsubscribeLabel")
526
+
l = l.With("did", user.Active.Did)
527
528
f, err := rp.repoResolver.Resolve(r)
529
if err != nil {
···
633
}
634
state := states[subject]
635
636
+
user := rp.oauth.GetMultiAccountUser(r)
637
rp.pages.LabelPanel(w, pages.LabelPanelParams{
638
LoggedInUser: user,
639
RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
···
681
}
682
state := states[subject]
683
684
+
user := rp.oauth.GetMultiAccountUser(r)
685
rp.pages.EditLabelPanel(w, pages.EditLabelPanelParams{
686
LoggedInUser: user,
687
RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
···
692
}
693
694
func (rp *Repo) AddCollaborator(w http.ResponseWriter, r *http.Request) {
695
+
user := rp.oauth.GetMultiAccountUser(r)
696
l := rp.logger.With("handler", "AddCollaborator")
697
+
l = l.With("did", user.Active.Did)
698
699
f, err := rp.repoResolver.Resolve(r)
700
if err != nil {
···
723
return
724
}
725
726
+
if collaboratorIdent.DID.String() == user.Active.Did {
727
fail("You seem to be adding yourself as a collaborator.", nil)
728
return
729
}
···
738
}
739
740
// emit a record
741
+
currentUser := rp.oauth.GetMultiAccountUser(r)
742
rkey := tid.TID()
743
createdAt := time.Now()
744
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
745
Collection: tangled.RepoCollaboratorNSID,
746
+
Repo: currentUser.Active.Did,
747
Rkey: rkey,
748
Record: &lexutil.LexiconTypeDecoder{
749
Val: &tangled.RepoCollaborator{
···
792
}
793
794
err = db.AddCollaborator(tx, models.Collaborator{
795
+
Did: syntax.DID(currentUser.Active.Did),
796
Rkey: rkey,
797
SubjectDid: collaboratorIdent.DID,
798
RepoAt: f.RepoAt(),
···
822
}
823
824
func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) {
825
+
user := rp.oauth.GetMultiAccountUser(r)
826
l := rp.logger.With("handler", "DeleteRepo")
827
828
noticeId := "operation-error"
···
840
}
841
_, err = comatproto.RepoDeleteRecord(r.Context(), atpClient, &comatproto.RepoDeleteRecord_Input{
842
Collection: tangled.RepoNSID,
843
+
Repo: user.Active.Did,
844
Rkey: f.Rkey,
845
})
846
if err != nil {
···
940
ref := chi.URLParam(r, "ref")
941
ref, _ = url.PathUnescape(ref)
942
943
+
user := rp.oauth.GetMultiAccountUser(r)
944
f, err := rp.repoResolver.Resolve(r)
945
if err != nil {
946
l.Error("failed to resolve source repo", "err", err)
···
969
r.Context(),
970
client,
971
&tangled.RepoForkSync_Input{
972
+
Did: user.Active.Did,
973
Name: f.Name,
974
Source: f.Source,
975
Branch: ref,
···
988
func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) {
989
l := rp.logger.With("handler", "ForkRepo")
990
991
+
user := rp.oauth.GetMultiAccountUser(r)
992
f, err := rp.repoResolver.Resolve(r)
993
if err != nil {
994
l.Error("failed to resolve source repo", "err", err)
···
997
998
switch r.Method {
999
case http.MethodGet:
1000
+
user := rp.oauth.GetMultiAccountUser(r)
1001
+
knots, err := rp.enforcer.GetKnotsForUser(user.Active.Did)
1002
if err != nil {
1003
rp.pages.Notice(w, "repo", "Invalid user account.")
1004
return
···
1020
}
1021
l = l.With("targetKnot", targetKnot)
1022
1023
+
ok, err := rp.enforcer.E.Enforce(user.Active.Did, targetKnot, targetKnot, "repo:create")
1024
if err != nil || !ok {
1025
rp.pages.Notice(w, "repo", "You do not have permission to create a repo in this knot.")
1026
return
···
1037
// in the user's account.
1038
existingRepo, err := db.GetRepo(
1039
rp.db,
1040
+
orm.FilterEq("did", user.Active.Did),
1041
orm.FilterEq("name", forkName),
1042
)
1043
if err != nil {
···
1066
// create an atproto record for this fork
1067
rkey := tid.TID()
1068
repo := &models.Repo{
1069
+
Did: user.Active.Did,
1070
Name: forkName,
1071
Knot: targetKnot,
1072
Rkey: rkey,
···
1086
1087
atresp, err := comatproto.RepoPutRecord(r.Context(), atpClient, &comatproto.RepoPutRecord_Input{
1088
Collection: tangled.RepoNSID,
1089
+
Repo: user.Active.Did,
1090
Rkey: rkey,
1091
Record: &lexutil.LexiconTypeDecoder{
1092
Val: &record,
···
1165
}
1166
1167
// acls
1168
+
p, _ := securejoin.SecureJoin(user.Active.Did, forkName)
1169
+
err = rp.enforcer.AddRepo(user.Active.Did, targetKnot, p)
1170
if err != nil {
1171
l.Error("failed to add ACLs", "err", err)
1172
rp.pages.Notice(w, "repo", "Failed to set up repository permissions.")
···
1191
aturi = ""
1192
1193
rp.notifier.NewRepo(r.Context(), repo)
1194
+
rp.pages.HxLocation(w, fmt.Sprintf("/%s/%s", user.Active.Did, forkName))
1195
}
1196
}
1197
+5
-5
appview/repo/settings.go
+5
-5
appview/repo/settings.go
···
79
}
80
81
func (rp *Repo) Secrets(w http.ResponseWriter, r *http.Request) {
82
-
user := rp.oauth.GetUser(r)
83
l := rp.logger.With("handler", "Secrets")
84
-
l = l.With("did", user.Did)
85
86
f, err := rp.repoResolver.Resolve(r)
87
if err != nil {
···
185
l := rp.logger.With("handler", "generalSettings")
186
187
f, err := rp.repoResolver.Resolve(r)
188
-
user := rp.oauth.GetUser(r)
189
190
scheme := "http"
191
if !rp.config.Core.Dev {
···
271
l := rp.logger.With("handler", "accessSettings")
272
273
f, err := rp.repoResolver.Resolve(r)
274
-
user := rp.oauth.GetUser(r)
275
276
collaborators, err := func(repo *models.Repo) ([]pages.Collaborator, error) {
277
repoCollaborators, err := rp.enforcer.E.GetImplicitUsersForResourceByDomain(repo.DidSlashRepo(), repo.Knot)
···
318
l := rp.logger.With("handler", "pipelineSettings")
319
320
f, err := rp.repoResolver.Resolve(r)
321
-
user := rp.oauth.GetUser(r)
322
323
// all spindles that the repo owner is a member of
324
spindles, err := rp.enforcer.GetSpindlesForUser(f.Did)
···
79
}
80
81
func (rp *Repo) Secrets(w http.ResponseWriter, r *http.Request) {
82
+
user := rp.oauth.GetMultiAccountUser(r)
83
l := rp.logger.With("handler", "Secrets")
84
+
l = l.With("did", user.Active.Did)
85
86
f, err := rp.repoResolver.Resolve(r)
87
if err != nil {
···
185
l := rp.logger.With("handler", "generalSettings")
186
187
f, err := rp.repoResolver.Resolve(r)
188
+
user := rp.oauth.GetMultiAccountUser(r)
189
190
scheme := "http"
191
if !rp.config.Core.Dev {
···
271
l := rp.logger.With("handler", "accessSettings")
272
273
f, err := rp.repoResolver.Resolve(r)
274
+
user := rp.oauth.GetMultiAccountUser(r)
275
276
collaborators, err := func(repo *models.Repo) ([]pages.Collaborator, error) {
277
repoCollaborators, err := rp.enforcer.E.GetImplicitUsersForResourceByDomain(repo.DidSlashRepo(), repo.Knot)
···
318
l := rp.logger.With("handler", "pipelineSettings")
319
320
f, err := rp.repoResolver.Resolve(r)
321
+
user := rp.oauth.GetMultiAccountUser(r)
322
323
// all spindles that the repo owner is a member of
324
spindles, err := rp.enforcer.GetSpindlesForUser(f.Did)
+1
-1
appview/repo/tree.go
+1
-1
appview/repo/tree.go
+4
-4
appview/reporesolver/resolver.go
+4
-4
appview/reporesolver/resolver.go
···
55
// 2. [x] remove `rr`, `CurrentDir`, `Ref` fields from `ResolvedRepo`
56
// 3. [x] remove `ResolvedRepo`
57
// 4. [ ] replace reporesolver to reposervice
58
-
func (rr *RepoResolver) GetRepoInfo(r *http.Request, user *oauth.User) repoinfo.RepoInfo {
59
ownerId, ook := r.Context().Value("resolvedId").(identity.Identity)
60
repo, rok := r.Context().Value("repo").(*models.Repo)
61
if !ook || !rok {
···
69
repoAt := repo.RepoAt()
70
isStarred := false
71
roles := repoinfo.RolesInRepo{}
72
-
if user != nil {
73
-
isStarred = db.GetStarStatus(rr.execer, user.Did, repoAt)
74
-
roles.Roles = rr.enforcer.GetPermissionsInRepo(user.Did, repo.Knot, repo.DidSlashRepo())
75
}
76
77
stats := repo.RepoStats
···
55
// 2. [x] remove `rr`, `CurrentDir`, `Ref` fields from `ResolvedRepo`
56
// 3. [x] remove `ResolvedRepo`
57
// 4. [ ] replace reporesolver to reposervice
58
+
func (rr *RepoResolver) GetRepoInfo(r *http.Request, user *oauth.MultiAccountUser) repoinfo.RepoInfo {
59
ownerId, ook := r.Context().Value("resolvedId").(identity.Identity)
60
repo, rok := r.Context().Value("repo").(*models.Repo)
61
if !ook || !rok {
···
69
repoAt := repo.RepoAt()
70
isStarred := false
71
roles := repoinfo.RolesInRepo{}
72
+
if user != nil && user.Active != nil {
73
+
isStarred = db.GetStarStatus(rr.execer, user.Active.Did, repoAt)
74
+
roles.Roles = rr.enforcer.GetPermissionsInRepo(user.Active.Did, repo.Knot, repo.DidSlashRepo())
75
}
76
77
stats := repo.RepoStats
+6
-6
appview/settings/settings.go
+6
-6
appview/settings/settings.go
···
81
}
82
83
func (s *Settings) profileSettings(w http.ResponseWriter, r *http.Request) {
84
-
user := s.OAuth.GetUser(r)
85
86
s.Pages.UserProfileSettings(w, pages.UserProfileSettingsParams{
87
LoggedInUser: user,
···
91
}
92
93
func (s *Settings) notificationsSettings(w http.ResponseWriter, r *http.Request) {
94
-
user := s.OAuth.GetUser(r)
95
did := s.OAuth.GetDid(r)
96
97
prefs, err := db.GetNotificationPreference(s.Db, did)
···
137
}
138
139
func (s *Settings) keysSettings(w http.ResponseWriter, r *http.Request) {
140
-
user := s.OAuth.GetUser(r)
141
-
pubKeys, err := db.GetPublicKeysForDid(s.Db, user.Did)
142
if err != nil {
143
log.Println(err)
144
}
···
152
}
153
154
func (s *Settings) emailsSettings(w http.ResponseWriter, r *http.Request) {
155
-
user := s.OAuth.GetUser(r)
156
-
emails, err := db.GetAllEmails(s.Db, user.Did)
157
if err != nil {
158
log.Println(err)
159
}
···
81
}
82
83
func (s *Settings) profileSettings(w http.ResponseWriter, r *http.Request) {
84
+
user := s.OAuth.GetMultiAccountUser(r)
85
86
s.Pages.UserProfileSettings(w, pages.UserProfileSettingsParams{
87
LoggedInUser: user,
···
91
}
92
93
func (s *Settings) notificationsSettings(w http.ResponseWriter, r *http.Request) {
94
+
user := s.OAuth.GetMultiAccountUser(r)
95
did := s.OAuth.GetDid(r)
96
97
prefs, err := db.GetNotificationPreference(s.Db, did)
···
137
}
138
139
func (s *Settings) keysSettings(w http.ResponseWriter, r *http.Request) {
140
+
user := s.OAuth.GetMultiAccountUser(r)
141
+
pubKeys, err := db.GetPublicKeysForDid(s.Db, user.Active.Did)
142
if err != nil {
143
log.Println(err)
144
}
···
152
}
153
154
func (s *Settings) emailsSettings(w http.ResponseWriter, r *http.Request) {
155
+
user := s.OAuth.GetMultiAccountUser(r)
156
+
emails, err := db.GetAllEmails(s.Db, user.Active.Did)
157
if err != nil {
158
log.Println(err)
159
}
+41
-41
appview/spindles/spindles.go
+41
-41
appview/spindles/spindles.go
···
69
}
70
71
func (s *Spindles) spindles(w http.ResponseWriter, r *http.Request) {
72
-
user := s.OAuth.GetUser(r)
73
all, err := db.GetSpindles(
74
s.Db,
75
-
orm.FilterEq("owner", user.Did),
76
)
77
if err != nil {
78
s.Logger.Error("failed to fetch spindles", "err", err)
···
91
func (s *Spindles) dashboard(w http.ResponseWriter, r *http.Request) {
92
l := s.Logger.With("handler", "dashboard")
93
94
-
user := s.OAuth.GetUser(r)
95
-
l = l.With("user", user.Did)
96
97
instance := chi.URLParam(r, "instance")
98
if instance == "" {
···
103
spindles, err := db.GetSpindles(
104
s.Db,
105
orm.FilterEq("instance", instance),
106
-
orm.FilterEq("owner", user.Did),
107
orm.FilterIsNot("verified", "null"),
108
)
109
if err != nil || len(spindles) != 1 {
···
155
//
156
// if the spindle is not up yet, the user is free to retry verification at a later point
157
func (s *Spindles) register(w http.ResponseWriter, r *http.Request) {
158
-
user := s.OAuth.GetUser(r)
159
l := s.Logger.With("handler", "register")
160
161
noticeId := "register-error"
···
176
return
177
}
178
l = l.With("instance", instance)
179
-
l = l.With("user", user.Did)
180
181
tx, err := s.Db.Begin()
182
if err != nil {
···
190
}()
191
192
err = db.AddSpindle(tx, models.Spindle{
193
-
Owner: syntax.DID(user.Did),
194
Instance: instance,
195
})
196
if err != nil {
···
214
return
215
}
216
217
-
ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.SpindleNSID, user.Did, instance)
218
var exCid *string
219
if ex != nil {
220
exCid = ex.Cid
···
223
// re-announce by registering under same rkey
224
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
225
Collection: tangled.SpindleNSID,
226
-
Repo: user.Did,
227
Rkey: instance,
228
Record: &lexutil.LexiconTypeDecoder{
229
Val: &tangled.Spindle{
···
254
}
255
256
// begin verification
257
-
err = serververify.RunVerification(r.Context(), instance, user.Did, s.Config.Core.Dev)
258
if err != nil {
259
l.Error("verification failed", "err", err)
260
s.Pages.HxRefresh(w)
261
return
262
}
263
264
-
_, err = serververify.MarkSpindleVerified(s.Db, s.Enforcer, instance, user.Did)
265
if err != nil {
266
l.Error("failed to mark verified", "err", err)
267
s.Pages.HxRefresh(w)
···
273
}
274
275
func (s *Spindles) delete(w http.ResponseWriter, r *http.Request) {
276
-
user := s.OAuth.GetUser(r)
277
l := s.Logger.With("handler", "delete")
278
279
noticeId := "operation-error"
···
291
292
spindles, err := db.GetSpindles(
293
s.Db,
294
-
orm.FilterEq("owner", user.Did),
295
orm.FilterEq("instance", instance),
296
)
297
if err != nil || len(spindles) != 1 {
···
300
return
301
}
302
303
-
if string(spindles[0].Owner) != user.Did {
304
-
l.Error("unauthorized", "user", user.Did, "owner", spindles[0].Owner)
305
s.Pages.Notice(w, noticeId, "Failed to delete spindle, unauthorized deletion attempt.")
306
return
307
}
···
320
// remove spindle members first
321
err = db.RemoveSpindleMember(
322
tx,
323
-
orm.FilterEq("did", user.Did),
324
orm.FilterEq("instance", instance),
325
)
326
if err != nil {
···
331
332
err = db.DeleteSpindle(
333
tx,
334
-
orm.FilterEq("owner", user.Did),
335
orm.FilterEq("instance", instance),
336
)
337
if err != nil {
···
359
360
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
361
Collection: tangled.SpindleNSID,
362
-
Repo: user.Did,
363
Rkey: instance,
364
})
365
if err != nil {
···
391
}
392
393
func (s *Spindles) retry(w http.ResponseWriter, r *http.Request) {
394
-
user := s.OAuth.GetUser(r)
395
l := s.Logger.With("handler", "retry")
396
397
noticeId := "operation-error"
···
407
return
408
}
409
l = l.With("instance", instance)
410
-
l = l.With("user", user.Did)
411
412
spindles, err := db.GetSpindles(
413
s.Db,
414
-
orm.FilterEq("owner", user.Did),
415
orm.FilterEq("instance", instance),
416
)
417
if err != nil || len(spindles) != 1 {
···
420
return
421
}
422
423
-
if string(spindles[0].Owner) != user.Did {
424
-
l.Error("unauthorized", "user", user.Did, "owner", spindles[0].Owner)
425
s.Pages.Notice(w, noticeId, "Failed to verify spindle, unauthorized verification attempt.")
426
return
427
}
428
429
// begin verification
430
-
err = serververify.RunVerification(r.Context(), instance, user.Did, s.Config.Core.Dev)
431
if err != nil {
432
l.Error("verification failed", "err", err)
433
···
445
return
446
}
447
448
-
rowId, err := serververify.MarkSpindleVerified(s.Db, s.Enforcer, instance, user.Did)
449
if err != nil {
450
l.Error("failed to mark verified", "err", err)
451
s.Pages.Notice(w, noticeId, err.Error())
···
473
}
474
475
func (s *Spindles) addMember(w http.ResponseWriter, r *http.Request) {
476
-
user := s.OAuth.GetUser(r)
477
l := s.Logger.With("handler", "addMember")
478
479
instance := chi.URLParam(r, "instance")
···
483
return
484
}
485
l = l.With("instance", instance)
486
-
l = l.With("user", user.Did)
487
488
spindles, err := db.GetSpindles(
489
s.Db,
490
-
orm.FilterEq("owner", user.Did),
491
orm.FilterEq("instance", instance),
492
)
493
if err != nil || len(spindles) != 1 {
···
502
s.Pages.Notice(w, noticeId, defaultErr)
503
}
504
505
-
if string(spindles[0].Owner) != user.Did {
506
-
l.Error("unauthorized", "user", user.Did, "owner", spindles[0].Owner)
507
s.Pages.Notice(w, noticeId, "Failed to add member, unauthorized attempt.")
508
return
509
}
···
552
553
// add member to db
554
if err = db.AddSpindleMember(tx, models.SpindleMember{
555
-
Did: syntax.DID(user.Did),
556
Rkey: rkey,
557
Instance: instance,
558
Subject: memberId.DID,
···
570
571
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
572
Collection: tangled.SpindleMemberNSID,
573
-
Repo: user.Did,
574
Rkey: rkey,
575
Record: &lexutil.LexiconTypeDecoder{
576
Val: &tangled.SpindleMember{
···
603
}
604
605
func (s *Spindles) removeMember(w http.ResponseWriter, r *http.Request) {
606
-
user := s.OAuth.GetUser(r)
607
l := s.Logger.With("handler", "removeMember")
608
609
noticeId := "operation-error"
···
619
return
620
}
621
l = l.With("instance", instance)
622
-
l = l.With("user", user.Did)
623
624
spindles, err := db.GetSpindles(
625
s.Db,
626
-
orm.FilterEq("owner", user.Did),
627
orm.FilterEq("instance", instance),
628
)
629
if err != nil || len(spindles) != 1 {
···
632
return
633
}
634
635
-
if string(spindles[0].Owner) != user.Did {
636
-
l.Error("unauthorized", "user", user.Did, "owner", spindles[0].Owner)
637
s.Pages.Notice(w, noticeId, "Failed to remove member, unauthorized attempt.")
638
return
639
}
···
668
// get the record from the DB first:
669
members, err := db.GetSpindleMembers(
670
s.Db,
671
-
orm.FilterEq("did", user.Did),
672
orm.FilterEq("instance", instance),
673
orm.FilterEq("subject", memberId.DID),
674
)
···
681
// remove from db
682
if err = db.RemoveSpindleMember(
683
tx,
684
-
orm.FilterEq("did", user.Did),
685
orm.FilterEq("instance", instance),
686
orm.FilterEq("subject", memberId.DID),
687
); err != nil {
···
707
// remove from pds
708
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
709
Collection: tangled.SpindleMemberNSID,
710
-
Repo: user.Did,
711
Rkey: members[0].Rkey,
712
})
713
if err != nil {
···
69
}
70
71
func (s *Spindles) spindles(w http.ResponseWriter, r *http.Request) {
72
+
user := s.OAuth.GetMultiAccountUser(r)
73
all, err := db.GetSpindles(
74
s.Db,
75
+
orm.FilterEq("owner", user.Active.Did),
76
)
77
if err != nil {
78
s.Logger.Error("failed to fetch spindles", "err", err)
···
91
func (s *Spindles) dashboard(w http.ResponseWriter, r *http.Request) {
92
l := s.Logger.With("handler", "dashboard")
93
94
+
user := s.OAuth.GetMultiAccountUser(r)
95
+
l = l.With("user", user.Active.Did)
96
97
instance := chi.URLParam(r, "instance")
98
if instance == "" {
···
103
spindles, err := db.GetSpindles(
104
s.Db,
105
orm.FilterEq("instance", instance),
106
+
orm.FilterEq("owner", user.Active.Did),
107
orm.FilterIsNot("verified", "null"),
108
)
109
if err != nil || len(spindles) != 1 {
···
155
//
156
// if the spindle is not up yet, the user is free to retry verification at a later point
157
func (s *Spindles) register(w http.ResponseWriter, r *http.Request) {
158
+
user := s.OAuth.GetMultiAccountUser(r)
159
l := s.Logger.With("handler", "register")
160
161
noticeId := "register-error"
···
176
return
177
}
178
l = l.With("instance", instance)
179
+
l = l.With("user", user.Active.Did)
180
181
tx, err := s.Db.Begin()
182
if err != nil {
···
190
}()
191
192
err = db.AddSpindle(tx, models.Spindle{
193
+
Owner: syntax.DID(user.Active.Did),
194
Instance: instance,
195
})
196
if err != nil {
···
214
return
215
}
216
217
+
ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.SpindleNSID, user.Active.Did, instance)
218
var exCid *string
219
if ex != nil {
220
exCid = ex.Cid
···
223
// re-announce by registering under same rkey
224
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
225
Collection: tangled.SpindleNSID,
226
+
Repo: user.Active.Did,
227
Rkey: instance,
228
Record: &lexutil.LexiconTypeDecoder{
229
Val: &tangled.Spindle{
···
254
}
255
256
// begin verification
257
+
err = serververify.RunVerification(r.Context(), instance, user.Active.Did, s.Config.Core.Dev)
258
if err != nil {
259
l.Error("verification failed", "err", err)
260
s.Pages.HxRefresh(w)
261
return
262
}
263
264
+
_, err = serververify.MarkSpindleVerified(s.Db, s.Enforcer, instance, user.Active.Did)
265
if err != nil {
266
l.Error("failed to mark verified", "err", err)
267
s.Pages.HxRefresh(w)
···
273
}
274
275
func (s *Spindles) delete(w http.ResponseWriter, r *http.Request) {
276
+
user := s.OAuth.GetMultiAccountUser(r)
277
l := s.Logger.With("handler", "delete")
278
279
noticeId := "operation-error"
···
291
292
spindles, err := db.GetSpindles(
293
s.Db,
294
+
orm.FilterEq("owner", user.Active.Did),
295
orm.FilterEq("instance", instance),
296
)
297
if err != nil || len(spindles) != 1 {
···
300
return
301
}
302
303
+
if string(spindles[0].Owner) != user.Active.Did {
304
+
l.Error("unauthorized", "user", user.Active.Did, "owner", spindles[0].Owner)
305
s.Pages.Notice(w, noticeId, "Failed to delete spindle, unauthorized deletion attempt.")
306
return
307
}
···
320
// remove spindle members first
321
err = db.RemoveSpindleMember(
322
tx,
323
+
orm.FilterEq("did", user.Active.Did),
324
orm.FilterEq("instance", instance),
325
)
326
if err != nil {
···
331
332
err = db.DeleteSpindle(
333
tx,
334
+
orm.FilterEq("owner", user.Active.Did),
335
orm.FilterEq("instance", instance),
336
)
337
if err != nil {
···
359
360
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
361
Collection: tangled.SpindleNSID,
362
+
Repo: user.Active.Did,
363
Rkey: instance,
364
})
365
if err != nil {
···
391
}
392
393
func (s *Spindles) retry(w http.ResponseWriter, r *http.Request) {
394
+
user := s.OAuth.GetMultiAccountUser(r)
395
l := s.Logger.With("handler", "retry")
396
397
noticeId := "operation-error"
···
407
return
408
}
409
l = l.With("instance", instance)
410
+
l = l.With("user", user.Active.Did)
411
412
spindles, err := db.GetSpindles(
413
s.Db,
414
+
orm.FilterEq("owner", user.Active.Did),
415
orm.FilterEq("instance", instance),
416
)
417
if err != nil || len(spindles) != 1 {
···
420
return
421
}
422
423
+
if string(spindles[0].Owner) != user.Active.Did {
424
+
l.Error("unauthorized", "user", user.Active.Did, "owner", spindles[0].Owner)
425
s.Pages.Notice(w, noticeId, "Failed to verify spindle, unauthorized verification attempt.")
426
return
427
}
428
429
// begin verification
430
+
err = serververify.RunVerification(r.Context(), instance, user.Active.Did, s.Config.Core.Dev)
431
if err != nil {
432
l.Error("verification failed", "err", err)
433
···
445
return
446
}
447
448
+
rowId, err := serververify.MarkSpindleVerified(s.Db, s.Enforcer, instance, user.Active.Did)
449
if err != nil {
450
l.Error("failed to mark verified", "err", err)
451
s.Pages.Notice(w, noticeId, err.Error())
···
473
}
474
475
func (s *Spindles) addMember(w http.ResponseWriter, r *http.Request) {
476
+
user := s.OAuth.GetMultiAccountUser(r)
477
l := s.Logger.With("handler", "addMember")
478
479
instance := chi.URLParam(r, "instance")
···
483
return
484
}
485
l = l.With("instance", instance)
486
+
l = l.With("user", user.Active.Did)
487
488
spindles, err := db.GetSpindles(
489
s.Db,
490
+
orm.FilterEq("owner", user.Active.Did),
491
orm.FilterEq("instance", instance),
492
)
493
if err != nil || len(spindles) != 1 {
···
502
s.Pages.Notice(w, noticeId, defaultErr)
503
}
504
505
+
if string(spindles[0].Owner) != user.Active.Did {
506
+
l.Error("unauthorized", "user", user.Active.Did, "owner", spindles[0].Owner)
507
s.Pages.Notice(w, noticeId, "Failed to add member, unauthorized attempt.")
508
return
509
}
···
552
553
// add member to db
554
if err = db.AddSpindleMember(tx, models.SpindleMember{
555
+
Did: syntax.DID(user.Active.Did),
556
Rkey: rkey,
557
Instance: instance,
558
Subject: memberId.DID,
···
570
571
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
572
Collection: tangled.SpindleMemberNSID,
573
+
Repo: user.Active.Did,
574
Rkey: rkey,
575
Record: &lexutil.LexiconTypeDecoder{
576
Val: &tangled.SpindleMember{
···
603
}
604
605
func (s *Spindles) removeMember(w http.ResponseWriter, r *http.Request) {
606
+
user := s.OAuth.GetMultiAccountUser(r)
607
l := s.Logger.With("handler", "removeMember")
608
609
noticeId := "operation-error"
···
619
return
620
}
621
l = l.With("instance", instance)
622
+
l = l.With("user", user.Active.Did)
623
624
spindles, err := db.GetSpindles(
625
s.Db,
626
+
orm.FilterEq("owner", user.Active.Did),
627
orm.FilterEq("instance", instance),
628
)
629
if err != nil || len(spindles) != 1 {
···
632
return
633
}
634
635
+
if string(spindles[0].Owner) != user.Active.Did {
636
+
l.Error("unauthorized", "user", user.Active.Did, "owner", spindles[0].Owner)
637
s.Pages.Notice(w, noticeId, "Failed to remove member, unauthorized attempt.")
638
return
639
}
···
668
// get the record from the DB first:
669
members, err := db.GetSpindleMembers(
670
s.Db,
671
+
orm.FilterEq("did", user.Active.Did),
672
orm.FilterEq("instance", instance),
673
orm.FilterEq("subject", memberId.DID),
674
)
···
681
// remove from db
682
if err = db.RemoveSpindleMember(
683
tx,
684
+
orm.FilterEq("did", user.Active.Did),
685
orm.FilterEq("instance", instance),
686
orm.FilterEq("subject", memberId.DID),
687
); err != nil {
···
707
// remove from pds
708
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
709
Collection: tangled.SpindleMemberNSID,
710
+
Repo: user.Active.Did,
711
Rkey: members[0].Rkey,
712
})
713
if err != nil {
+7
-7
appview/state/follow.go
+7
-7
appview/state/follow.go
···
15
)
16
17
func (s *State) Follow(w http.ResponseWriter, r *http.Request) {
18
-
currentUser := s.oauth.GetUser(r)
19
20
subject := r.URL.Query().Get("subject")
21
if subject == "" {
···
29
return
30
}
31
32
-
if currentUser.Did == subjectIdent.DID.String() {
33
log.Println("cant follow or unfollow yourself")
34
return
35
}
···
46
rkey := tid.TID()
47
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
48
Collection: tangled.GraphFollowNSID,
49
-
Repo: currentUser.Did,
50
Rkey: rkey,
51
Record: &lexutil.LexiconTypeDecoder{
52
Val: &tangled.GraphFollow{
···
62
log.Println("created atproto record: ", resp.Uri)
63
64
follow := &models.Follow{
65
-
UserDid: currentUser.Did,
66
SubjectDid: subjectIdent.DID.String(),
67
Rkey: rkey,
68
}
···
89
return
90
case http.MethodDelete:
91
// find the record in the db
92
-
follow, err := db.GetFollow(s.db, currentUser.Did, subjectIdent.DID.String())
93
if err != nil {
94
log.Println("failed to get follow relationship")
95
return
···
97
98
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
99
Collection: tangled.GraphFollowNSID,
100
-
Repo: currentUser.Did,
101
Rkey: follow.Rkey,
102
})
103
···
106
return
107
}
108
109
-
err = db.DeleteFollowByRkey(s.db, currentUser.Did, follow.Rkey)
110
if err != nil {
111
log.Println("failed to delete follow from DB")
112
// this is not an issue, the firehose event might have already done this
···
15
)
16
17
func (s *State) Follow(w http.ResponseWriter, r *http.Request) {
18
+
currentUser := s.oauth.GetMultiAccountUser(r)
19
20
subject := r.URL.Query().Get("subject")
21
if subject == "" {
···
29
return
30
}
31
32
+
if currentUser.Active.Did == subjectIdent.DID.String() {
33
log.Println("cant follow or unfollow yourself")
34
return
35
}
···
46
rkey := tid.TID()
47
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
48
Collection: tangled.GraphFollowNSID,
49
+
Repo: currentUser.Active.Did,
50
Rkey: rkey,
51
Record: &lexutil.LexiconTypeDecoder{
52
Val: &tangled.GraphFollow{
···
62
log.Println("created atproto record: ", resp.Uri)
63
64
follow := &models.Follow{
65
+
UserDid: currentUser.Active.Did,
66
SubjectDid: subjectIdent.DID.String(),
67
Rkey: rkey,
68
}
···
89
return
90
case http.MethodDelete:
91
// find the record in the db
92
+
follow, err := db.GetFollow(s.db, currentUser.Active.Did, subjectIdent.DID.String())
93
if err != nil {
94
log.Println("failed to get follow relationship")
95
return
···
97
98
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
99
Collection: tangled.GraphFollowNSID,
100
+
Repo: currentUser.Active.Did,
101
Rkey: follow.Rkey,
102
})
103
···
106
return
107
}
108
109
+
err = db.DeleteFollowByRkey(s.db, currentUser.Active.Did, follow.Rkey)
110
if err != nil {
111
log.Println("failed to delete follow from DB")
112
// this is not an issue, the firehose event might have already done this
+1
-1
appview/state/gfi.go
+1
-1
appview/state/gfi.go
+32
-32
appview/state/profile.go
+32
-32
appview/state/profile.go
···
77
return nil, fmt.Errorf("failed to get follower stats: %w", err)
78
}
79
80
-
loggedInUser := s.oauth.GetUser(r)
81
followStatus := models.IsNotFollowing
82
if loggedInUser != nil {
83
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
84
}
85
86
now := time.Now()
···
174
}
175
176
s.pages.ProfileOverview(w, pages.ProfileOverviewParams{
177
-
LoggedInUser: s.oauth.GetUser(r),
178
Card: profile,
179
Repos: pinnedRepos,
180
CollaboratingRepos: pinnedCollaboratingRepos,
···
205
}
206
207
err = s.pages.ProfileRepos(w, pages.ProfileReposParams{
208
-
LoggedInUser: s.oauth.GetUser(r),
209
Repos: repos,
210
Card: profile,
211
})
···
234
}
235
236
err = s.pages.ProfileStarred(w, pages.ProfileStarredParams{
237
-
LoggedInUser: s.oauth.GetUser(r),
238
Repos: repos,
239
Card: profile,
240
})
···
259
}
260
261
err = s.pages.ProfileStrings(w, pages.ProfileStringsParams{
262
-
LoggedInUser: s.oauth.GetUser(r),
263
Strings: strings,
264
Card: profile,
265
})
···
283
}
284
l = l.With("profileDid", profile.UserDid)
285
286
-
loggedInUser := s.oauth.GetUser(r)
287
params := FollowsPageParams{
288
Card: profile,
289
}
···
316
317
loggedInUserFollowing := make(map[string]struct{})
318
if loggedInUser != nil {
319
-
following, err := db.GetFollowing(s.db, loggedInUser.Did)
320
if err != nil {
321
-
l.Error("failed to get follow list", "err", err, "loggedInUser", loggedInUser.Did)
322
return ¶ms, err
323
}
324
loggedInUserFollowing = make(map[string]struct{}, len(following))
···
333
followStatus := models.IsNotFollowing
334
if _, exists := loggedInUserFollowing[did]; exists {
335
followStatus = models.IsFollowing
336
-
} else if loggedInUser != nil && loggedInUser.Did == did {
337
followStatus = models.IsSelf
338
}
339
···
367
}
368
369
s.pages.ProfileFollowers(w, pages.ProfileFollowersParams{
370
-
LoggedInUser: s.oauth.GetUser(r),
371
Followers: followPage.Follows,
372
Card: followPage.Card,
373
})
···
381
}
382
383
s.pages.ProfileFollowing(w, pages.ProfileFollowingParams{
384
-
LoggedInUser: s.oauth.GetUser(r),
385
Following: followPage.Follows,
386
Card: followPage.Card,
387
})
···
530
}
531
532
func (s *State) UpdateProfileBio(w http.ResponseWriter, r *http.Request) {
533
-
user := s.oauth.GetUser(r)
534
535
err := r.ParseForm()
536
if err != nil {
···
539
return
540
}
541
542
-
profile, err := db.GetProfile(s.db, user.Did)
543
if err != nil {
544
-
log.Printf("getting profile data for %s: %s", user.Did, err)
545
}
546
547
profile.Description = r.FormValue("description")
···
578
}
579
580
func (s *State) UpdateProfilePins(w http.ResponseWriter, r *http.Request) {
581
-
user := s.oauth.GetUser(r)
582
583
err := r.ParseForm()
584
if err != nil {
···
587
return
588
}
589
590
-
profile, err := db.GetProfile(s.db, user.Did)
591
if err != nil {
592
-
log.Printf("getting profile data for %s: %s", user.Did, err)
593
}
594
595
i := 0
···
617
}
618
619
func (s *State) updateProfile(profile *models.Profile, w http.ResponseWriter, r *http.Request) {
620
-
user := s.oauth.GetUser(r)
621
tx, err := s.db.BeginTx(r.Context(), nil)
622
if err != nil {
623
log.Println("failed to start transaction", err)
···
644
vanityStats = append(vanityStats, string(v.Kind))
645
}
646
647
-
ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.ActorProfileNSID, user.Did, "self")
648
var cid *string
649
if ex != nil {
650
cid = ex.Cid
···
652
653
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
654
Collection: tangled.ActorProfileNSID,
655
-
Repo: user.Did,
656
Rkey: "self",
657
Record: &lexutil.LexiconTypeDecoder{
658
Val: &tangled.ActorProfile{
···
681
682
s.notifier.UpdateProfile(r.Context(), profile)
683
684
-
s.pages.HxRedirect(w, "/"+user.Did)
685
}
686
687
func (s *State) EditBioFragment(w http.ResponseWriter, r *http.Request) {
688
-
user := s.oauth.GetUser(r)
689
690
-
profile, err := db.GetProfile(s.db, user.Did)
691
if err != nil {
692
-
log.Printf("getting profile data for %s: %s", user.Did, err)
693
}
694
695
s.pages.EditBioFragment(w, pages.EditBioParams{
···
699
}
700
701
func (s *State) EditPinsFragment(w http.ResponseWriter, r *http.Request) {
702
-
user := s.oauth.GetUser(r)
703
704
-
profile, err := db.GetProfile(s.db, user.Did)
705
if err != nil {
706
-
log.Printf("getting profile data for %s: %s", user.Did, err)
707
}
708
709
-
repos, err := db.GetRepos(s.db, 0, orm.FilterEq("did", user.Did))
710
if err != nil {
711
-
log.Printf("getting repos for %s: %s", user.Did, err)
712
}
713
714
-
collaboratingRepos, err := db.CollaboratingIn(s.db, user.Did)
715
if err != nil {
716
-
log.Printf("getting collaborating repos for %s: %s", user.Did, err)
717
}
718
719
allRepos := []pages.PinnedRepo{}
···
77
return nil, fmt.Errorf("failed to get follower stats: %w", err)
78
}
79
80
+
loggedInUser := s.oauth.GetMultiAccountUser(r)
81
followStatus := models.IsNotFollowing
82
if loggedInUser != nil {
83
+
followStatus = db.GetFollowStatus(s.db, loggedInUser.Active.Did, did)
84
}
85
86
now := time.Now()
···
174
}
175
176
s.pages.ProfileOverview(w, pages.ProfileOverviewParams{
177
+
LoggedInUser: s.oauth.GetMultiAccountUser(r),
178
Card: profile,
179
Repos: pinnedRepos,
180
CollaboratingRepos: pinnedCollaboratingRepos,
···
205
}
206
207
err = s.pages.ProfileRepos(w, pages.ProfileReposParams{
208
+
LoggedInUser: s.oauth.GetMultiAccountUser(r),
209
Repos: repos,
210
Card: profile,
211
})
···
234
}
235
236
err = s.pages.ProfileStarred(w, pages.ProfileStarredParams{
237
+
LoggedInUser: s.oauth.GetMultiAccountUser(r),
238
Repos: repos,
239
Card: profile,
240
})
···
259
}
260
261
err = s.pages.ProfileStrings(w, pages.ProfileStringsParams{
262
+
LoggedInUser: s.oauth.GetMultiAccountUser(r),
263
Strings: strings,
264
Card: profile,
265
})
···
283
}
284
l = l.With("profileDid", profile.UserDid)
285
286
+
loggedInUser := s.oauth.GetMultiAccountUser(r)
287
params := FollowsPageParams{
288
Card: profile,
289
}
···
316
317
loggedInUserFollowing := make(map[string]struct{})
318
if loggedInUser != nil {
319
+
following, err := db.GetFollowing(s.db, loggedInUser.Active.Did)
320
if err != nil {
321
+
l.Error("failed to get follow list", "err", err, "loggedInUser", loggedInUser.Active.Did)
322
return ¶ms, err
323
}
324
loggedInUserFollowing = make(map[string]struct{}, len(following))
···
333
followStatus := models.IsNotFollowing
334
if _, exists := loggedInUserFollowing[did]; exists {
335
followStatus = models.IsFollowing
336
+
} else if loggedInUser != nil && loggedInUser.Active.Did == did {
337
followStatus = models.IsSelf
338
}
339
···
367
}
368
369
s.pages.ProfileFollowers(w, pages.ProfileFollowersParams{
370
+
LoggedInUser: s.oauth.GetMultiAccountUser(r),
371
Followers: followPage.Follows,
372
Card: followPage.Card,
373
})
···
381
}
382
383
s.pages.ProfileFollowing(w, pages.ProfileFollowingParams{
384
+
LoggedInUser: s.oauth.GetMultiAccountUser(r),
385
Following: followPage.Follows,
386
Card: followPage.Card,
387
})
···
530
}
531
532
func (s *State) UpdateProfileBio(w http.ResponseWriter, r *http.Request) {
533
+
user := s.oauth.GetMultiAccountUser(r)
534
535
err := r.ParseForm()
536
if err != nil {
···
539
return
540
}
541
542
+
profile, err := db.GetProfile(s.db, user.Active.Did)
543
if err != nil {
544
+
log.Printf("getting profile data for %s: %s", user.Active.Did, err)
545
}
546
547
profile.Description = r.FormValue("description")
···
578
}
579
580
func (s *State) UpdateProfilePins(w http.ResponseWriter, r *http.Request) {
581
+
user := s.oauth.GetMultiAccountUser(r)
582
583
err := r.ParseForm()
584
if err != nil {
···
587
return
588
}
589
590
+
profile, err := db.GetProfile(s.db, user.Active.Did)
591
if err != nil {
592
+
log.Printf("getting profile data for %s: %s", user.Active.Did, err)
593
}
594
595
i := 0
···
617
}
618
619
func (s *State) updateProfile(profile *models.Profile, w http.ResponseWriter, r *http.Request) {
620
+
user := s.oauth.GetMultiAccountUser(r)
621
tx, err := s.db.BeginTx(r.Context(), nil)
622
if err != nil {
623
log.Println("failed to start transaction", err)
···
644
vanityStats = append(vanityStats, string(v.Kind))
645
}
646
647
+
ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.ActorProfileNSID, user.Active.Did, "self")
648
var cid *string
649
if ex != nil {
650
cid = ex.Cid
···
652
653
_, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
654
Collection: tangled.ActorProfileNSID,
655
+
Repo: user.Active.Did,
656
Rkey: "self",
657
Record: &lexutil.LexiconTypeDecoder{
658
Val: &tangled.ActorProfile{
···
681
682
s.notifier.UpdateProfile(r.Context(), profile)
683
684
+
s.pages.HxRedirect(w, "/"+user.Active.Did)
685
}
686
687
func (s *State) EditBioFragment(w http.ResponseWriter, r *http.Request) {
688
+
user := s.oauth.GetMultiAccountUser(r)
689
690
+
profile, err := db.GetProfile(s.db, user.Active.Did)
691
if err != nil {
692
+
log.Printf("getting profile data for %s: %s", user.Active.Did, err)
693
}
694
695
s.pages.EditBioFragment(w, pages.EditBioParams{
···
699
}
700
701
func (s *State) EditPinsFragment(w http.ResponseWriter, r *http.Request) {
702
+
user := s.oauth.GetMultiAccountUser(r)
703
704
+
profile, err := db.GetProfile(s.db, user.Active.Did)
705
if err != nil {
706
+
log.Printf("getting profile data for %s: %s", user.Active.Did, err)
707
}
708
709
+
repos, err := db.GetRepos(s.db, 0, orm.FilterEq("did", user.Active.Did))
710
if err != nil {
711
+
log.Printf("getting repos for %s: %s", user.Active.Did, err)
712
}
713
714
+
collaboratingRepos, err := db.CollaboratingIn(s.db, user.Active.Did)
715
if err != nil {
716
+
log.Printf("getting collaborating repos for %s: %s", user.Active.Did, err)
717
}
718
719
allRepos := []pages.PinnedRepo{}
+7
-7
appview/state/reaction.go
+7
-7
appview/state/reaction.go
···
17
)
18
19
func (s *State) React(w http.ResponseWriter, r *http.Request) {
20
-
currentUser := s.oauth.GetUser(r)
21
22
subject := r.URL.Query().Get("subject")
23
if subject == "" {
···
49
rkey := tid.TID()
50
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
51
Collection: tangled.FeedReactionNSID,
52
-
Repo: currentUser.Did,
53
Rkey: rkey,
54
Record: &lexutil.LexiconTypeDecoder{
55
Val: &tangled.FeedReaction{
···
64
return
65
}
66
67
-
err = db.AddReaction(s.db, currentUser.Did, subjectUri, reactionKind, rkey)
68
if err != nil {
69
log.Println("failed to react", err)
70
return
···
87
88
return
89
case http.MethodDelete:
90
-
reaction, err := db.GetReaction(s.db, currentUser.Did, subjectUri, reactionKind)
91
if err != nil {
92
-
log.Println("failed to get reaction relationship for", currentUser.Did, subjectUri)
93
return
94
}
95
96
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
97
Collection: tangled.FeedReactionNSID,
98
-
Repo: currentUser.Did,
99
Rkey: reaction.Rkey,
100
})
101
···
104
return
105
}
106
107
-
err = db.DeleteReactionByRkey(s.db, currentUser.Did, reaction.Rkey)
108
if err != nil {
109
log.Println("failed to delete reaction from DB")
110
// this is not an issue, the firehose event might have already done this
···
17
)
18
19
func (s *State) React(w http.ResponseWriter, r *http.Request) {
20
+
currentUser := s.oauth.GetMultiAccountUser(r)
21
22
subject := r.URL.Query().Get("subject")
23
if subject == "" {
···
49
rkey := tid.TID()
50
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
51
Collection: tangled.FeedReactionNSID,
52
+
Repo: currentUser.Active.Did,
53
Rkey: rkey,
54
Record: &lexutil.LexiconTypeDecoder{
55
Val: &tangled.FeedReaction{
···
64
return
65
}
66
67
+
err = db.AddReaction(s.db, currentUser.Active.Did, subjectUri, reactionKind, rkey)
68
if err != nil {
69
log.Println("failed to react", err)
70
return
···
87
88
return
89
case http.MethodDelete:
90
+
reaction, err := db.GetReaction(s.db, currentUser.Active.Did, subjectUri, reactionKind)
91
if err != nil {
92
+
log.Println("failed to get reaction relationship for", currentUser.Active.Did, subjectUri)
93
return
94
}
95
96
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
97
Collection: tangled.FeedReactionNSID,
98
+
Repo: currentUser.Active.Did,
99
Rkey: reaction.Rkey,
100
})
101
···
104
return
105
}
106
107
+
err = db.DeleteReactionByRkey(s.db, currentUser.Active.Did, reaction.Rkey)
108
if err != nil {
109
log.Println("failed to delete reaction from DB")
110
// this is not an issue, the firehose event might have already done this
+6
-6
appview/state/star.go
+6
-6
appview/state/star.go
···
16
)
17
18
func (s *State) Star(w http.ResponseWriter, r *http.Request) {
19
-
currentUser := s.oauth.GetUser(r)
20
21
subject := r.URL.Query().Get("subject")
22
if subject == "" {
···
42
rkey := tid.TID()
43
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
44
Collection: tangled.FeedStarNSID,
45
-
Repo: currentUser.Did,
46
Rkey: rkey,
47
Record: &lexutil.LexiconTypeDecoder{
48
Val: &tangled.FeedStar{
···
57
log.Println("created atproto record: ", resp.Uri)
58
59
star := &models.Star{
60
-
Did: currentUser.Did,
61
RepoAt: subjectUri,
62
Rkey: rkey,
63
}
···
84
return
85
case http.MethodDelete:
86
// find the record in the db
87
-
star, err := db.GetStar(s.db, currentUser.Did, subjectUri)
88
if err != nil {
89
log.Println("failed to get star relationship")
90
return
···
92
93
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
94
Collection: tangled.FeedStarNSID,
95
-
Repo: currentUser.Did,
96
Rkey: star.Rkey,
97
})
98
···
101
return
102
}
103
104
-
err = db.DeleteStarByRkey(s.db, currentUser.Did, star.Rkey)
105
if err != nil {
106
log.Println("failed to delete star from DB")
107
// this is not an issue, the firehose event might have already done this
···
16
)
17
18
func (s *State) Star(w http.ResponseWriter, r *http.Request) {
19
+
currentUser := s.oauth.GetMultiAccountUser(r)
20
21
subject := r.URL.Query().Get("subject")
22
if subject == "" {
···
42
rkey := tid.TID()
43
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
44
Collection: tangled.FeedStarNSID,
45
+
Repo: currentUser.Active.Did,
46
Rkey: rkey,
47
Record: &lexutil.LexiconTypeDecoder{
48
Val: &tangled.FeedStar{
···
57
log.Println("created atproto record: ", resp.Uri)
58
59
star := &models.Star{
60
+
Did: currentUser.Active.Did,
61
RepoAt: subjectUri,
62
Rkey: rkey,
63
}
···
84
return
85
case http.MethodDelete:
86
// find the record in the db
87
+
star, err := db.GetStar(s.db, currentUser.Active.Did, subjectUri)
88
if err != nil {
89
log.Println("failed to get star relationship")
90
return
···
92
93
_, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
94
Collection: tangled.FeedStarNSID,
95
+
Repo: currentUser.Active.Did,
96
Rkey: star.Rkey,
97
})
98
···
101
return
102
}
103
104
+
err = db.DeleteStarByRkey(s.db, currentUser.Active.Did, star.Rkey)
105
if err != nil {
106
log.Println("failed to delete star from DB")
107
// this is not an issue, the firehose event might have already done this
+22
-22
appview/state/state.go
+22
-22
appview/state/state.go
···
213
}
214
215
func (s *State) TermsOfService(w http.ResponseWriter, r *http.Request) {
216
-
user := s.oauth.GetUser(r)
217
s.pages.TermsOfService(w, pages.TermsOfServiceParams{
218
LoggedInUser: user,
219
})
220
}
221
222
func (s *State) PrivacyPolicy(w http.ResponseWriter, r *http.Request) {
223
-
user := s.oauth.GetUser(r)
224
s.pages.PrivacyPolicy(w, pages.PrivacyPolicyParams{
225
LoggedInUser: user,
226
})
227
}
228
229
func (s *State) Brand(w http.ResponseWriter, r *http.Request) {
230
-
user := s.oauth.GetUser(r)
231
s.pages.Brand(w, pages.BrandParams{
232
LoggedInUser: user,
233
})
234
}
235
236
func (s *State) HomeOrTimeline(w http.ResponseWriter, r *http.Request) {
237
-
if s.oauth.GetUser(r) != nil {
238
s.Timeline(w, r)
239
return
240
}
···
242
}
243
244
func (s *State) Timeline(w http.ResponseWriter, r *http.Request) {
245
-
user := s.oauth.GetUser(r)
246
247
// TODO: set this flag based on the UI
248
filtered := false
249
250
var userDid string
251
-
if user != nil {
252
-
userDid = user.Did
253
}
254
timeline, err := db.MakeTimeline(s.db, 50, userDid, filtered)
255
if err != nil {
···
278
}
279
280
func (s *State) UpgradeBanner(w http.ResponseWriter, r *http.Request) {
281
-
user := s.oauth.GetUser(r)
282
if user == nil {
283
return
284
}
285
286
l := s.logger.With("handler", "UpgradeBanner")
287
-
l = l.With("did", user.Did)
288
289
regs, err := db.GetRegistrations(
290
s.db,
291
-
orm.FilterEq("did", user.Did),
292
orm.FilterEq("needs_upgrade", 1),
293
)
294
if err != nil {
···
297
298
spindles, err := db.GetSpindles(
299
s.db,
300
-
orm.FilterEq("owner", user.Did),
301
orm.FilterEq("needs_upgrade", 1),
302
)
303
if err != nil {
···
411
func (s *State) NewRepo(w http.ResponseWriter, r *http.Request) {
412
switch r.Method {
413
case http.MethodGet:
414
-
user := s.oauth.GetUser(r)
415
-
knots, err := s.enforcer.GetKnotsForUser(user.Did)
416
if err != nil {
417
s.pages.Notice(w, "repo", "Invalid user account.")
418
return
···
426
case http.MethodPost:
427
l := s.logger.With("handler", "NewRepo")
428
429
-
user := s.oauth.GetUser(r)
430
-
l = l.With("did", user.Did)
431
432
// form validation
433
domain := r.FormValue("domain")
···
459
description := r.FormValue("description")
460
461
// ACL validation
462
-
ok, err := s.enforcer.E.Enforce(user.Did, domain, domain, "repo:create")
463
if err != nil || !ok {
464
l.Info("unauthorized")
465
s.pages.Notice(w, "repo", "You do not have permission to create a repo in this knot.")
···
469
// Check for existing repos
470
existingRepo, err := db.GetRepo(
471
s.db,
472
-
orm.FilterEq("did", user.Did),
473
orm.FilterEq("name", repoName),
474
)
475
if err == nil && existingRepo != nil {
···
481
// create atproto record for this repo
482
rkey := tid.TID()
483
repo := &models.Repo{
484
-
Did: user.Did,
485
Name: repoName,
486
Knot: domain,
487
Rkey: rkey,
···
500
501
atresp, err := comatproto.RepoPutRecord(r.Context(), atpClient, &comatproto.RepoPutRecord_Input{
502
Collection: tangled.RepoNSID,
503
-
Repo: user.Did,
504
Rkey: rkey,
505
Record: &lexutil.LexiconTypeDecoder{
506
Val: &record,
···
577
}
578
579
// acls
580
-
p, _ := securejoin.SecureJoin(user.Did, repoName)
581
-
err = s.enforcer.AddRepo(user.Did, domain, p)
582
if err != nil {
583
l.Error("acl setup failed", "err", err)
584
s.pages.Notice(w, "repo", "Failed to set up repository permissions.")
···
603
aturi = ""
604
605
s.notifier.NewRepo(r.Context(), repo)
606
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/%s", user.Did, repoName))
607
}
608
}
609
···
213
}
214
215
func (s *State) TermsOfService(w http.ResponseWriter, r *http.Request) {
216
+
user := s.oauth.GetMultiAccountUser(r)
217
s.pages.TermsOfService(w, pages.TermsOfServiceParams{
218
LoggedInUser: user,
219
})
220
}
221
222
func (s *State) PrivacyPolicy(w http.ResponseWriter, r *http.Request) {
223
+
user := s.oauth.GetMultiAccountUser(r)
224
s.pages.PrivacyPolicy(w, pages.PrivacyPolicyParams{
225
LoggedInUser: user,
226
})
227
}
228
229
func (s *State) Brand(w http.ResponseWriter, r *http.Request) {
230
+
user := s.oauth.GetMultiAccountUser(r)
231
s.pages.Brand(w, pages.BrandParams{
232
LoggedInUser: user,
233
})
234
}
235
236
func (s *State) HomeOrTimeline(w http.ResponseWriter, r *http.Request) {
237
+
if s.oauth.GetMultiAccountUser(r) != nil {
238
s.Timeline(w, r)
239
return
240
}
···
242
}
243
244
func (s *State) Timeline(w http.ResponseWriter, r *http.Request) {
245
+
user := s.oauth.GetMultiAccountUser(r)
246
247
// TODO: set this flag based on the UI
248
filtered := false
249
250
var userDid string
251
+
if user != nil && user.Active != nil {
252
+
userDid = user.Active.Did
253
}
254
timeline, err := db.MakeTimeline(s.db, 50, userDid, filtered)
255
if err != nil {
···
278
}
279
280
func (s *State) UpgradeBanner(w http.ResponseWriter, r *http.Request) {
281
+
user := s.oauth.GetMultiAccountUser(r)
282
if user == nil {
283
return
284
}
285
286
l := s.logger.With("handler", "UpgradeBanner")
287
+
l = l.With("did", user.Active.Did)
288
289
regs, err := db.GetRegistrations(
290
s.db,
291
+
orm.FilterEq("did", user.Active.Did),
292
orm.FilterEq("needs_upgrade", 1),
293
)
294
if err != nil {
···
297
298
spindles, err := db.GetSpindles(
299
s.db,
300
+
orm.FilterEq("owner", user.Active.Did),
301
orm.FilterEq("needs_upgrade", 1),
302
)
303
if err != nil {
···
411
func (s *State) NewRepo(w http.ResponseWriter, r *http.Request) {
412
switch r.Method {
413
case http.MethodGet:
414
+
user := s.oauth.GetMultiAccountUser(r)
415
+
knots, err := s.enforcer.GetKnotsForUser(user.Active.Did)
416
if err != nil {
417
s.pages.Notice(w, "repo", "Invalid user account.")
418
return
···
426
case http.MethodPost:
427
l := s.logger.With("handler", "NewRepo")
428
429
+
user := s.oauth.GetMultiAccountUser(r)
430
+
l = l.With("did", user.Active.Did)
431
432
// form validation
433
domain := r.FormValue("domain")
···
459
description := r.FormValue("description")
460
461
// ACL validation
462
+
ok, err := s.enforcer.E.Enforce(user.Active.Did, domain, domain, "repo:create")
463
if err != nil || !ok {
464
l.Info("unauthorized")
465
s.pages.Notice(w, "repo", "You do not have permission to create a repo in this knot.")
···
469
// Check for existing repos
470
existingRepo, err := db.GetRepo(
471
s.db,
472
+
orm.FilterEq("did", user.Active.Did),
473
orm.FilterEq("name", repoName),
474
)
475
if err == nil && existingRepo != nil {
···
481
// create atproto record for this repo
482
rkey := tid.TID()
483
repo := &models.Repo{
484
+
Did: user.Active.Did,
485
Name: repoName,
486
Knot: domain,
487
Rkey: rkey,
···
500
501
atresp, err := comatproto.RepoPutRecord(r.Context(), atpClient, &comatproto.RepoPutRecord_Input{
502
Collection: tangled.RepoNSID,
503
+
Repo: user.Active.Did,
504
Rkey: rkey,
505
Record: &lexutil.LexiconTypeDecoder{
506
Val: &record,
···
577
}
578
579
// acls
580
+
p, _ := securejoin.SecureJoin(user.Active.Did, repoName)
581
+
err = s.enforcer.AddRepo(user.Active.Did, domain, p)
582
if err != nil {
583
l.Error("acl setup failed", "err", err)
584
s.pages.Notice(w, "repo", "Failed to set up repository permissions.")
···
603
aturi = ""
604
605
s.notifier.NewRepo(r.Context(), repo)
606
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/%s", user.Active.Did, repoName))
607
}
608
}
609
+19
-19
appview/strings/strings.go
+19
-19
appview/strings/strings.go
···
82
}
83
84
s.Pages.StringsTimeline(w, pages.StringTimelineParams{
85
-
LoggedInUser: s.OAuth.GetUser(r),
86
Strings: strings,
87
})
88
}
···
153
if err != nil {
154
l.Error("failed to get star count", "err", err)
155
}
156
-
user := s.OAuth.GetUser(r)
157
isStarred := false
158
if user != nil {
159
-
isStarred = db.GetStarStatus(s.Db, user.Did, string.AtUri())
160
}
161
162
s.Pages.SingleString(w, pages.SingleStringParams{
···
178
func (s *Strings) edit(w http.ResponseWriter, r *http.Request) {
179
l := s.Logger.With("handler", "edit")
180
181
-
user := s.OAuth.GetUser(r)
182
183
id, ok := r.Context().Value("resolvedId").(identity.Identity)
184
if !ok {
···
216
first := all[0]
217
218
// verify that the logged in user owns this string
219
-
if user.Did != id.DID.String() {
220
-
l.Error("unauthorized request", "expected", id.DID, "got", user.Did)
221
w.WriteHeader(http.StatusUnauthorized)
222
return
223
}
···
226
case http.MethodGet:
227
// return the form with prefilled fields
228
s.Pages.PutString(w, pages.PutStringParams{
229
-
LoggedInUser: s.OAuth.GetUser(r),
230
Action: "edit",
231
String: first,
232
})
···
299
s.Notifier.EditString(r.Context(), &entry)
300
301
// if that went okay, redir to the string
302
-
s.Pages.HxRedirect(w, "/strings/"+user.Did+"/"+entry.Rkey)
303
}
304
305
}
306
307
func (s *Strings) create(w http.ResponseWriter, r *http.Request) {
308
l := s.Logger.With("handler", "create")
309
-
user := s.OAuth.GetUser(r)
310
311
switch r.Method {
312
case http.MethodGet:
313
s.Pages.PutString(w, pages.PutStringParams{
314
-
LoggedInUser: s.OAuth.GetUser(r),
315
Action: "new",
316
})
317
case http.MethodPost:
···
335
description := r.FormValue("description")
336
337
string := models.String{
338
-
Did: syntax.DID(user.Did),
339
Rkey: tid.TID(),
340
Filename: filename,
341
Description: description,
···
353
354
resp, err := comatproto.RepoPutRecord(r.Context(), client, &atproto.RepoPutRecord_Input{
355
Collection: tangled.StringNSID,
356
-
Repo: user.Did,
357
Rkey: string.Rkey,
358
Record: &lexutil.LexiconTypeDecoder{
359
Val: &record,
···
375
s.Notifier.NewString(r.Context(), &string)
376
377
// successful
378
-
s.Pages.HxRedirect(w, "/strings/"+user.Did+"/"+string.Rkey)
379
}
380
}
381
382
func (s *Strings) delete(w http.ResponseWriter, r *http.Request) {
383
l := s.Logger.With("handler", "create")
384
-
user := s.OAuth.GetUser(r)
385
fail := func(msg string, err error) {
386
l.Error(msg, "err", err)
387
s.Pages.Notice(w, "error", msg)
···
402
return
403
}
404
405
-
if user.Did != id.DID.String() {
406
-
fail("You cannot delete this string", fmt.Errorf("unauthorized deletion, %s != %s", user.Did, id.DID.String()))
407
return
408
}
409
410
if err := db.DeleteString(
411
s.Db,
412
-
orm.FilterEq("did", user.Did),
413
orm.FilterEq("rkey", rkey),
414
); err != nil {
415
fail("Failed to delete string.", err)
416
return
417
}
418
419
-
s.Notifier.DeleteString(r.Context(), user.Did, rkey)
420
421
-
s.Pages.HxRedirect(w, "/strings/"+user.Did)
422
}
423
424
func (s *Strings) comment(w http.ResponseWriter, r *http.Request) {
···
82
}
83
84
s.Pages.StringsTimeline(w, pages.StringTimelineParams{
85
+
LoggedInUser: s.OAuth.GetMultiAccountUser(r),
86
Strings: strings,
87
})
88
}
···
153
if err != nil {
154
l.Error("failed to get star count", "err", err)
155
}
156
+
user := s.OAuth.GetMultiAccountUser(r)
157
isStarred := false
158
if user != nil {
159
+
isStarred = db.GetStarStatus(s.Db, user.Active.Did, string.AtUri())
160
}
161
162
s.Pages.SingleString(w, pages.SingleStringParams{
···
178
func (s *Strings) edit(w http.ResponseWriter, r *http.Request) {
179
l := s.Logger.With("handler", "edit")
180
181
+
user := s.OAuth.GetMultiAccountUser(r)
182
183
id, ok := r.Context().Value("resolvedId").(identity.Identity)
184
if !ok {
···
216
first := all[0]
217
218
// verify that the logged in user owns this string
219
+
if user.Active.Did != id.DID.String() {
220
+
l.Error("unauthorized request", "expected", id.DID, "got", user.Active.Did)
221
w.WriteHeader(http.StatusUnauthorized)
222
return
223
}
···
226
case http.MethodGet:
227
// return the form with prefilled fields
228
s.Pages.PutString(w, pages.PutStringParams{
229
+
LoggedInUser: s.OAuth.GetMultiAccountUser(r),
230
Action: "edit",
231
String: first,
232
})
···
299
s.Notifier.EditString(r.Context(), &entry)
300
301
// if that went okay, redir to the string
302
+
s.Pages.HxRedirect(w, "/strings/"+user.Active.Did+"/"+entry.Rkey)
303
}
304
305
}
306
307
func (s *Strings) create(w http.ResponseWriter, r *http.Request) {
308
l := s.Logger.With("handler", "create")
309
+
user := s.OAuth.GetMultiAccountUser(r)
310
311
switch r.Method {
312
case http.MethodGet:
313
s.Pages.PutString(w, pages.PutStringParams{
314
+
LoggedInUser: s.OAuth.GetMultiAccountUser(r),
315
Action: "new",
316
})
317
case http.MethodPost:
···
335
description := r.FormValue("description")
336
337
string := models.String{
338
+
Did: syntax.DID(user.Active.Did),
339
Rkey: tid.TID(),
340
Filename: filename,
341
Description: description,
···
353
354
resp, err := comatproto.RepoPutRecord(r.Context(), client, &atproto.RepoPutRecord_Input{
355
Collection: tangled.StringNSID,
356
+
Repo: user.Active.Did,
357
Rkey: string.Rkey,
358
Record: &lexutil.LexiconTypeDecoder{
359
Val: &record,
···
375
s.Notifier.NewString(r.Context(), &string)
376
377
// successful
378
+
s.Pages.HxRedirect(w, "/strings/"+user.Active.Did+"/"+string.Rkey)
379
}
380
}
381
382
func (s *Strings) delete(w http.ResponseWriter, r *http.Request) {
383
l := s.Logger.With("handler", "create")
384
+
user := s.OAuth.GetMultiAccountUser(r)
385
fail := func(msg string, err error) {
386
l.Error(msg, "err", err)
387
s.Pages.Notice(w, "error", msg)
···
402
return
403
}
404
405
+
if user.Active.Did != id.DID.String() {
406
+
fail("You cannot delete this string", fmt.Errorf("unauthorized deletion, %s != %s", user.Active.Did, id.DID.String()))
407
return
408
}
409
410
if err := db.DeleteString(
411
s.Db,
412
+
orm.FilterEq("did", user.Active.Did),
413
orm.FilterEq("rkey", rkey),
414
); err != nil {
415
fail("Failed to delete string.", err)
416
return
417
}
418
419
+
s.Notifier.DeleteString(r.Context(), user.Active.Did, rkey)
420
421
+
s.Pages.HxRedirect(w, "/strings/"+user.Active.Did)
422
}
423
424
func (s *Strings) comment(w http.ResponseWriter, r *http.Request) {
History
3 rounds
2 comments
expand 0 comments
pull request successfully merged
expand 0 comments
expand 2 comments
oh wait, sorry I get it now. we need full account list for rendering. Makes sense.
Hopefully #800 can make this better...
can you explain why we are switching to
GetMultiAccountUser?