···81818282func (rp *Issues) RepoSingleIssue(w http.ResponseWriter, r *http.Request) {
8383 l := rp.logger.With("handler", "RepoSingleIssue")
8484- user := rp.oauth.GetMultiAccountUser(r)
8484+ user := rp.oauth.GetUser(r)
8585 f, err := rp.repoResolver.Resolve(r)
8686 if err != nil {
8787 l.Error("failed to get repo and knot", "err", err)
···102102103103 userReactions := map[models.ReactionKind]bool{}
104104 if user != nil {
105105- userReactions = db.GetReactionStatusMap(rp.db, user.Active.Did, issue.AtUri())
105105+ userReactions = db.GetReactionStatusMap(rp.db, user.Did, issue.AtUri())
106106 }
107107108108 backlinks, err := db.GetBacklinks(rp.db, issue.AtUri())
···143143144144func (rp *Issues) EditIssue(w http.ResponseWriter, r *http.Request) {
145145 l := rp.logger.With("handler", "EditIssue")
146146- user := rp.oauth.GetMultiAccountUser(r)
146146+ user := rp.oauth.GetUser(r)
147147148148 issue, ok := r.Context().Value("issue").(*models.Issue)
149149 if !ok {
···182182 return
183183 }
184184185185- ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueNSID, user.Active.Did, newIssue.Rkey)
185185+ ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueNSID, user.Did, newIssue.Rkey)
186186 if err != nil {
187187 l.Error("failed to get record", "err", err)
188188 rp.pages.Notice(w, noticeId, "Failed to edit issue, no record found on PDS.")
···191191192192 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
193193 Collection: tangled.RepoIssueNSID,
194194- Repo: user.Active.Did,
194194+ Repo: user.Did,
195195 Rkey: newIssue.Rkey,
196196 SwapRecord: ex.Cid,
197197 Record: &lexutil.LexiconTypeDecoder{
···292292293293func (rp *Issues) CloseIssue(w http.ResponseWriter, r *http.Request) {
294294 l := rp.logger.With("handler", "CloseIssue")
295295- user := rp.oauth.GetMultiAccountUser(r)
295295+ user := rp.oauth.GetUser(r)
296296 f, err := rp.repoResolver.Resolve(r)
297297 if err != nil {
298298 l.Error("failed to get repo and knot", "err", err)
···306306 return
307307 }
308308309309- roles := repoinfo.RolesInRepo{Roles: rp.enforcer.GetPermissionsInRepo(user.Active.Did, f.Knot, f.DidSlashRepo())}
309309+ roles := repoinfo.RolesInRepo{Roles: rp.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo())}
310310 isRepoOwner := roles.IsOwner()
311311 isCollaborator := roles.IsCollaborator()
312312- isIssueOwner := user.Active.Did == issue.Did
312312+ isIssueOwner := user.Did == issue.Did
313313314314 // TODO: make this more granular
315315 if isIssueOwner || isRepoOwner || isCollaborator {
···326326 issue.Open = false
327327328328 // notify about the issue closure
329329- rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Active.Did), issue)
329329+ rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Did), issue)
330330331331 ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
332332 rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
···340340341341func (rp *Issues) ReopenIssue(w http.ResponseWriter, r *http.Request) {
342342 l := rp.logger.With("handler", "ReopenIssue")
343343- user := rp.oauth.GetMultiAccountUser(r)
343343+ user := rp.oauth.GetUser(r)
344344 f, err := rp.repoResolver.Resolve(r)
345345 if err != nil {
346346 l.Error("failed to get repo and knot", "err", err)
···354354 return
355355 }
356356357357- roles := repoinfo.RolesInRepo{Roles: rp.enforcer.GetPermissionsInRepo(user.Active.Did, f.Knot, f.DidSlashRepo())}
357357+ roles := repoinfo.RolesInRepo{Roles: rp.enforcer.GetPermissionsInRepo(user.Did, f.Knot, f.DidSlashRepo())}
358358 isRepoOwner := roles.IsOwner()
359359 isCollaborator := roles.IsCollaborator()
360360- isIssueOwner := user.Active.Did == issue.Did
360360+ isIssueOwner := user.Did == issue.Did
361361362362 if isCollaborator || isRepoOwner || isIssueOwner {
363363 err := db.ReopenIssues(
···373373 issue.Open = true
374374375375 // notify about the issue reopen
376376- rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Active.Did), issue)
376376+ rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Did), issue)
377377378378 ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)
379379 rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
···387387388388func (rp *Issues) NewIssueComment(w http.ResponseWriter, r *http.Request) {
389389 l := rp.logger.With("handler", "NewIssueComment")
390390- user := rp.oauth.GetMultiAccountUser(r)
390390+ user := rp.oauth.GetUser(r)
391391 f, err := rp.repoResolver.Resolve(r)
392392 if err != nil {
393393 l.Error("failed to get repo and knot", "err", err)
···416416 mentions, references := rp.mentionsResolver.Resolve(r.Context(), body)
417417418418 comment := models.IssueComment{
419419- Did: user.Active.Did,
419419+ Did: user.Did,
420420 Rkey: tid.TID(),
421421 IssueAt: issue.AtUri().String(),
422422 ReplyTo: replyTo,
···495495496496func (rp *Issues) IssueComment(w http.ResponseWriter, r *http.Request) {
497497 l := rp.logger.With("handler", "IssueComment")
498498- user := rp.oauth.GetMultiAccountUser(r)
498498+ user := rp.oauth.GetUser(r)
499499500500 issue, ok := r.Context().Value("issue").(*models.Issue)
501501 if !ok {
···531531532532func (rp *Issues) EditIssueComment(w http.ResponseWriter, r *http.Request) {
533533 l := rp.logger.With("handler", "EditIssueComment")
534534- user := rp.oauth.GetMultiAccountUser(r)
534534+ user := rp.oauth.GetUser(r)
535535536536 issue, ok := r.Context().Value("issue").(*models.Issue)
537537 if !ok {
···557557 }
558558 comment := comments[0]
559559560560- if comment.Did != user.Active.Did {
561561- l.Error("unauthorized comment edit", "expectedDid", comment.Did, "gotDid", user.Active.Did)
560560+ if comment.Did != user.Did {
561561+ l.Error("unauthorized comment edit", "expectedDid", comment.Did, "gotDid", user.Did)
562562 http.Error(w, "you are not the author of this comment", http.StatusUnauthorized)
563563 return
564564 }
···608608 // rkey is optional, it was introduced later
609609 if newComment.Rkey != "" {
610610 // update the record on pds
611611- ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueCommentNSID, user.Active.Did, comment.Rkey)
611611+ ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueCommentNSID, user.Did, comment.Rkey)
612612 if err != nil {
613613 l.Error("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey)
614614 rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "Failed to update description, no record found on PDS.")
···617617618618 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
619619 Collection: tangled.RepoIssueCommentNSID,
620620- Repo: user.Active.Did,
620620+ Repo: user.Did,
621621 Rkey: newComment.Rkey,
622622 SwapRecord: ex.Cid,
623623 Record: &lexutil.LexiconTypeDecoder{
···641641642642func (rp *Issues) ReplyIssueCommentPlaceholder(w http.ResponseWriter, r *http.Request) {
643643 l := rp.logger.With("handler", "ReplyIssueCommentPlaceholder")
644644- user := rp.oauth.GetMultiAccountUser(r)
644644+ user := rp.oauth.GetUser(r)
645645646646 issue, ok := r.Context().Value("issue").(*models.Issue)
647647 if !ok {
···677677678678func (rp *Issues) ReplyIssueComment(w http.ResponseWriter, r *http.Request) {
679679 l := rp.logger.With("handler", "ReplyIssueComment")
680680- user := rp.oauth.GetMultiAccountUser(r)
680680+ user := rp.oauth.GetUser(r)
681681682682 issue, ok := r.Context().Value("issue").(*models.Issue)
683683 if !ok {
···713713714714func (rp *Issues) DeleteIssueComment(w http.ResponseWriter, r *http.Request) {
715715 l := rp.logger.With("handler", "DeleteIssueComment")
716716- user := rp.oauth.GetMultiAccountUser(r)
716716+ user := rp.oauth.GetUser(r)
717717718718 issue, ok := r.Context().Value("issue").(*models.Issue)
719719 if !ok {
···739739 }
740740 comment := comments[0]
741741742742- if comment.Did != user.Active.Did {
743743- l.Error("unauthorized action", "expectedDid", comment.Did, "gotDid", user.Active.Did)
742742+ if comment.Did != user.Did {
743743+ l.Error("unauthorized action", "expectedDid", comment.Did, "gotDid", user.Did)
744744 http.Error(w, "you are not the author of this comment", http.StatusUnauthorized)
745745 return
746746 }
···769769 }
770770 _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
771771 Collection: tangled.RepoIssueCommentNSID,
772772- Repo: user.Active.Did,
772772+ Repo: user.Did,
773773 Rkey: comment.Rkey,
774774 })
775775 if err != nil {
···807807808808 page := pagination.FromContext(r.Context())
809809810810- user := rp.oauth.GetMultiAccountUser(r)
810810+ user := rp.oauth.GetUser(r)
811811 f, err := rp.repoResolver.Resolve(r)
812812 if err != nil {
813813 l.Error("failed to get repo and knot", "err", err)
···884884 }
885885886886 rp.pages.RepoIssues(w, pages.RepoIssuesParams{
887887- LoggedInUser: rp.oauth.GetMultiAccountUser(r),
887887+ LoggedInUser: rp.oauth.GetUser(r),
888888 RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
889889 Issues: issues,
890890 IssueCount: totalIssues,
···897897898898func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) {
899899 l := rp.logger.With("handler", "NewIssue")
900900- user := rp.oauth.GetMultiAccountUser(r)
900900+ user := rp.oauth.GetUser(r)
901901902902 f, err := rp.repoResolver.Resolve(r)
903903 if err != nil {
···921921 Title: r.FormValue("title"),
922922 Body: body,
923923 Open: true,
924924- Did: user.Active.Did,
924924+ Did: user.Did,
925925 Created: time.Now(),
926926 Mentions: mentions,
927927 References: references,
···945945 }
946946 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
947947 Collection: tangled.RepoIssueNSID,
948948- Repo: user.Active.Did,
948948+ Repo: user.Did,
949949 Rkey: issue.Rkey,
950950 Record: &lexutil.LexiconTypeDecoder{
951951 Val: &record,
+31-31
appview/knots/knots.go
···7070}
71717272func (k *Knots) knots(w http.ResponseWriter, r *http.Request) {
7373- user := k.OAuth.GetMultiAccountUser(r)
7373+ user := k.OAuth.GetUser(r)
7474 registrations, err := db.GetRegistrations(
7575 k.Db,
7676- orm.FilterEq("did", user.Active.Did),
7676+ orm.FilterEq("did", user.Did),
7777 )
7878 if err != nil {
7979 k.Logger.Error("failed to fetch knot registrations", "err", err)
···9292func (k *Knots) dashboard(w http.ResponseWriter, r *http.Request) {
9393 l := k.Logger.With("handler", "dashboard")
94949595- user := k.OAuth.GetMultiAccountUser(r)
9696- l = l.With("user", user.Active.Did)
9595+ user := k.OAuth.GetUser(r)
9696+ l = l.With("user", user.Did)
97979898 domain := chi.URLParam(r, "domain")
9999 if domain == "" {
···103103104104 registrations, err := db.GetRegistrations(
105105 k.Db,
106106- orm.FilterEq("did", user.Active.Did),
106106+ orm.FilterEq("did", user.Did),
107107 orm.FilterEq("domain", domain),
108108 )
109109 if err != nil {
···154154}
155155156156func (k *Knots) register(w http.ResponseWriter, r *http.Request) {
157157- user := k.OAuth.GetMultiAccountUser(r)
157157+ user := k.OAuth.GetUser(r)
158158 l := k.Logger.With("handler", "register")
159159160160 noticeId := "register-error"
···175175 return
176176 }
177177 l = l.With("domain", domain)
178178- l = l.With("user", user.Active.Did)
178178+ l = l.With("user", user.Did)
179179180180 tx, err := k.Db.Begin()
181181 if err != nil {
···188188 k.Enforcer.E.LoadPolicy()
189189 }()
190190191191- err = db.AddKnot(tx, domain, user.Active.Did)
191191+ err = db.AddKnot(tx, domain, user.Did)
192192 if err != nil {
193193 l.Error("failed to insert", "err", err)
194194 fail()
···210210 return
211211 }
212212213213- ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.KnotNSID, user.Active.Did, domain)
213213+ ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.KnotNSID, user.Did, domain)
214214 var exCid *string
215215 if ex != nil {
216216 exCid = ex.Cid
···219219 // re-announce by registering under same rkey
220220 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
221221 Collection: tangled.KnotNSID,
222222- Repo: user.Active.Did,
222222+ Repo: user.Did,
223223 Rkey: domain,
224224 Record: &lexutil.LexiconTypeDecoder{
225225 Val: &tangled.Knot{
···250250 }
251251252252 // begin verification
253253- err = serververify.RunVerification(r.Context(), domain, user.Active.Did, k.Config.Core.Dev)
253253+ err = serververify.RunVerification(r.Context(), domain, user.Did, k.Config.Core.Dev)
254254 if err != nil {
255255 l.Error("verification failed", "err", err)
256256 k.Pages.HxRefresh(w)
257257 return
258258 }
259259260260- err = serververify.MarkKnotVerified(k.Db, k.Enforcer, domain, user.Active.Did)
260260+ err = serververify.MarkKnotVerified(k.Db, k.Enforcer, domain, user.Did)
261261 if err != nil {
262262 l.Error("failed to mark verified", "err", err)
263263 k.Pages.HxRefresh(w)
···275275}
276276277277func (k *Knots) delete(w http.ResponseWriter, r *http.Request) {
278278- user := k.OAuth.GetMultiAccountUser(r)
278278+ user := k.OAuth.GetUser(r)
279279 l := k.Logger.With("handler", "delete")
280280281281 noticeId := "operation-error"
···294294 // get record from db first
295295 registrations, err := db.GetRegistrations(
296296 k.Db,
297297- orm.FilterEq("did", user.Active.Did),
297297+ orm.FilterEq("did", user.Did),
298298 orm.FilterEq("domain", domain),
299299 )
300300 if err != nil {
···322322323323 err = db.DeleteKnot(
324324 tx,
325325- orm.FilterEq("did", user.Active.Did),
325325+ orm.FilterEq("did", user.Did),
326326 orm.FilterEq("domain", domain),
327327 )
328328 if err != nil {
···350350351351 _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
352352 Collection: tangled.KnotNSID,
353353- Repo: user.Active.Did,
353353+ Repo: user.Did,
354354 Rkey: domain,
355355 })
356356 if err != nil {
···382382}
383383384384func (k *Knots) retry(w http.ResponseWriter, r *http.Request) {
385385- user := k.OAuth.GetMultiAccountUser(r)
385385+ user := k.OAuth.GetUser(r)
386386 l := k.Logger.With("handler", "retry")
387387388388 noticeId := "operation-error"
···398398 return
399399 }
400400 l = l.With("domain", domain)
401401- l = l.With("user", user.Active.Did)
401401+ l = l.With("user", user.Did)
402402403403 // get record from db first
404404 registrations, err := db.GetRegistrations(
405405 k.Db,
406406- orm.FilterEq("did", user.Active.Did),
406406+ orm.FilterEq("did", user.Did),
407407 orm.FilterEq("domain", domain),
408408 )
409409 if err != nil {
···419419 registration := registrations[0]
420420421421 // begin verification
422422- err = serververify.RunVerification(r.Context(), domain, user.Active.Did, k.Config.Core.Dev)
422422+ err = serververify.RunVerification(r.Context(), domain, user.Did, k.Config.Core.Dev)
423423 if err != nil {
424424 l.Error("verification failed", "err", err)
425425···437437 return
438438 }
439439440440- err = serververify.MarkKnotVerified(k.Db, k.Enforcer, domain, user.Active.Did)
440440+ err = serververify.MarkKnotVerified(k.Db, k.Enforcer, domain, user.Did)
441441 if err != nil {
442442 l.Error("failed to mark verified", "err", err)
443443 k.Pages.Notice(w, noticeId, err.Error())
···456456 return
457457 }
458458459459- ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.KnotNSID, user.Active.Did, domain)
459459+ ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", tangled.KnotNSID, user.Did, domain)
460460 var exCid *string
461461 if ex != nil {
462462 exCid = ex.Cid
···465465 // ignore the error here
466466 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
467467 Collection: tangled.KnotNSID,
468468- Repo: user.Active.Did,
468468+ Repo: user.Did,
469469 Rkey: domain,
470470 Record: &lexutil.LexiconTypeDecoder{
471471 Val: &tangled.Knot{
···494494 // Get updated registration to show
495495 registrations, err = db.GetRegistrations(
496496 k.Db,
497497- orm.FilterEq("did", user.Active.Did),
497497+ orm.FilterEq("did", user.Did),
498498 orm.FilterEq("domain", domain),
499499 )
500500 if err != nil {
···516516}
517517518518func (k *Knots) addMember(w http.ResponseWriter, r *http.Request) {
519519- user := k.OAuth.GetMultiAccountUser(r)
519519+ user := k.OAuth.GetUser(r)
520520 l := k.Logger.With("handler", "addMember")
521521522522 domain := chi.URLParam(r, "domain")
···526526 return
527527 }
528528 l = l.With("domain", domain)
529529- l = l.With("user", user.Active.Did)
529529+ l = l.With("user", user.Did)
530530531531 registrations, err := db.GetRegistrations(
532532 k.Db,
533533- orm.FilterEq("did", user.Active.Did),
533533+ orm.FilterEq("did", user.Did),
534534 orm.FilterEq("domain", domain),
535535 orm.FilterIsNot("registered", "null"),
536536 )
···583583584584 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
585585 Collection: tangled.KnotMemberNSID,
586586- Repo: user.Active.Did,
586586+ Repo: user.Did,
587587 Rkey: rkey,
588588 Record: &lexutil.LexiconTypeDecoder{
589589 Val: &tangled.KnotMember{
···618618}
619619620620func (k *Knots) removeMember(w http.ResponseWriter, r *http.Request) {
621621- user := k.OAuth.GetMultiAccountUser(r)
621621+ user := k.OAuth.GetUser(r)
622622 l := k.Logger.With("handler", "removeMember")
623623624624 noticeId := "operation-error"
···634634 return
635635 }
636636 l = l.With("domain", domain)
637637- l = l.With("user", user.Active.Did)
637637+ l = l.With("user", user.Did)
638638639639 registrations, err := db.GetRegistrations(
640640 k.Db,
641641- orm.FilterEq("did", user.Active.Did),
641641+ orm.FilterEq("did", user.Did),
642642 orm.FilterEq("domain", domain),
643643 orm.FilterIsNot("registered", "null"),
644644 )
+2-2
appview/labels/labels.go
···6868// - this handler should calculate the diff in order to create the labelop record
6969// - we need the diff in order to maintain a "history" of operations performed by users
7070func (l *Labels) PerformLabelOp(w http.ResponseWriter, r *http.Request) {
7171- user := l.oauth.GetMultiAccountUser(r)
7171+ user := l.oauth.GetUser(r)
72727373 noticeId := "add-label-error"
7474···8282 return
8383 }
84848585- did := user.Active.Did
8585+ did := user.Did
8686 rkey := tid.TID()
8787 performedAt := time.Now()
8888 indexedAt := time.Now()
+8-6
appview/middleware/middleware.go
···115115 return func(next http.Handler) http.Handler {
116116 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
117117 // requires auth also
118118- actor := mw.oauth.GetMultiAccountUser(r)
118118+ actor := mw.oauth.GetUser(r)
119119 if actor == nil {
120120 // we need a logged in user
121121 log.Printf("not logged in, redirecting")
···128128 return
129129 }
130130131131- ok, err := mw.enforcer.E.HasGroupingPolicy(actor.Active.Did, group, domain)
131131+ ok, err := mw.enforcer.E.HasGroupingPolicy(actor.Did, group, domain)
132132 if err != nil || !ok {
133133- log.Printf("%s does not have perms of a %s in domain %s", actor.Active.Did, group, domain)
133133+ // we need a logged in user
134134+ log.Printf("%s does not have perms of a %s in domain %s", actor.Did, group, domain)
134135 http.Error(w, "Forbiden", http.StatusUnauthorized)
135136 return
136137 }
···148149 return func(next http.Handler) http.Handler {
149150 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
150151 // requires auth also
151151- actor := mw.oauth.GetMultiAccountUser(r)
152152+ actor := mw.oauth.GetUser(r)
152153 if actor == nil {
153154 // we need a logged in user
154155 log.Printf("not logged in, redirecting")
···161162 return
162163 }
163164164164- ok, err := mw.enforcer.E.Enforce(actor.Active.Did, f.Knot, f.DidSlashRepo(), requiredPerm)
165165+ ok, err := mw.enforcer.E.Enforce(actor.Did, f.Knot, f.DidSlashRepo(), requiredPerm)
165166 if err != nil || !ok {
166166- log.Printf("%s does not have perms of a %s in repo %s", actor.Active.Did, requiredPerm, f.DidSlashRepo())
167167+ // we need a logged in user
168168+ log.Printf("%s does not have perms of a %s in repo %s", actor.Did, requiredPerm, f.DidSlashRepo())
167169 http.Error(w, "Forbiden", http.StatusUnauthorized)
168170 return
169171 }
-48
appview/models/pipeline.go
···11package models
2233import (
44- "fmt"
54 "slices"
66- "strings"
75 "time"
8697 "github.com/bluesky-social/indigo/atproto/syntax"
108 "github.com/go-git/go-git/v5/plumbing"
1111- "tangled.org/core/api/tangled"
129 spindle "tangled.org/core/spindle/models"
1310 "tangled.org/core/workflow"
1411)
···2825 Statuses map[string]WorkflowStatus
2926}
30273131-func (p *Pipeline) AtUri() syntax.ATURI {
3232- return syntax.ATURI(fmt.Sprintf("at://did:web:%s/%s/%s", p.Knot, tangled.PipelineNSID, p.Rkey))
3333-}
3434-3528type WorkflowStatus struct {
3629 Data []PipelineStatus
3730}
···5952 return 0
6053}
61546262-// produces short summary of successes:
6363-// - "0/4" when zero successes of 4 workflows
6464-// - "4/4" when all successes of 4 workflows
6565-// - "0/0" when no workflows run in this pipeline
6666-func (p Pipeline) ShortStatusSummary() string {
6767- counts := make(map[spindle.StatusKind]int)
6868- for _, w := range p.Statuses {
6969- counts[w.Latest().Status] += 1
7070- }
7171-7272- total := len(p.Statuses)
7373- successes := counts[spindle.StatusKindSuccess]
7474-7575- return fmt.Sprintf("%d/%d", successes, total)
7676-}
7777-7878-// produces a string of the form "3/4 success, 2/4 failed, 1/4 pending"
7979-func (p Pipeline) LongStatusSummary() string {
8080- counts := make(map[spindle.StatusKind]int)
8181- for _, w := range p.Statuses {
8282- counts[w.Latest().Status] += 1
8383- }
8484-8585- total := len(p.Statuses)
8686-8787- var result []string
8888- // finish states first, followed by start states
8989- states := append(spindle.FinishStates[:], spindle.StartStates[:]...)
9090- for _, state := range states {
9191- if count, ok := counts[state]; ok {
9292- result = append(result, fmt.Sprintf("%d/%d %s", count, total, state.String()))
9393- }
9494- }
9595-9696- return strings.Join(result, ", ")
9797-}
9898-9955func (p Pipeline) Counts() map[string]int {
10056 m := make(map[string]int)
10157 for _, w := range p.Statuses {
···172128 Error *string
173129 ExitCode int
174130}
175175-176176-func (ps *PipelineStatus) PipelineAt() syntax.ATURI {
177177- return syntax.ATURI(fmt.Sprintf("at://did:web:%s/%s/%s", ps.PipelineKnot, tangled.PipelineNSID, ps.PipelineRkey))
178178-}
+17-7
appview/models/pull.go
···171171 return syntax.ATURI(p.CommentAt)
172172}
173173174174-func (p *Pull) TotalComments() int {
175175- total := 0
176176- for _, s := range p.Submissions {
177177- total += len(s.Comments)
178178- }
179179- return total
180180-}
174174+// func (p *PullComment) AsRecord() tangled.RepoPullComment {
175175+// mentions := make([]string, len(p.Mentions))
176176+// for i, did := range p.Mentions {
177177+// mentions[i] = string(did)
178178+// }
179179+// references := make([]string, len(p.References))
180180+// for i, uri := range p.References {
181181+// references[i] = string(uri)
182182+// }
183183+// return tangled.RepoPullComment{
184184+// Pull: p.PullAt,
185185+// Body: p.Body,
186186+// Mentions: mentions,
187187+// References: references,
188188+// CreatedAt: p.Created.Format(time.RFC3339),
189189+// }
190190+// }
181191182192func (p *Pull) LastRoundNumber() int {
183193 return len(p.Submissions) - 1
+6-7
appview/notifications/notifications.go
···48484949func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request) {
5050 l := n.logger.With("handler", "notificationsPage")
5151- user := n.oauth.GetMultiAccountUser(r)
5151+ user := n.oauth.GetUser(r)
52525353 page := pagination.FromContext(r.Context())
54545555 total, err := db.CountNotifications(
5656 n.db,
5757- orm.FilterEq("recipient_did", user.Active.Did),
5757+ orm.FilterEq("recipient_did", user.Did),
5858 )
5959 if err != nil {
6060 l.Error("failed to get total notifications", "err", err)
···6565 notifications, err := db.GetNotificationsWithEntities(
6666 n.db,
6767 page,
6868- orm.FilterEq("recipient_did", user.Active.Did),
6868+ orm.FilterEq("recipient_did", user.Did),
6969 )
7070 if err != nil {
7171 l.Error("failed to get notifications", "err", err)
···7373 return
7474 }
75757676- err = db.MarkAllNotificationsRead(n.db, user.Active.Did)
7676+ err = db.MarkAllNotificationsRead(n.db, user.Did)
7777 if err != nil {
7878 l.Error("failed to mark notifications as read", "err", err)
7979 }
···9090}
91919292func (n *Notifications) getUnreadCount(w http.ResponseWriter, r *http.Request) {
9393- user := n.oauth.GetMultiAccountUser(r)
9393+ user := n.oauth.GetUser(r)
9494 if user == nil {
9595- http.Error(w, "Forbidden", http.StatusUnauthorized)
9695 return
9796 }
98979998 count, err := db.CountNotifications(
10099 n.db,
101101- orm.FilterEq("recipient_did", user.Active.Did),
100100+ orm.FilterEq("recipient_did", user.Did),
102101 orm.FilterEq("read", 0),
103102 )
104103 if err != nil {
···3030 <div class="mx-6">
3131 These services may not be fully accessible until upgraded.
3232 <a class="underline text-red-800 dark:text-red-200"
3333- href="https://docs.tangled.org/migrating-knots-and-spindles.html">
3333+ href="https://docs.tangled.org/migrating-knots-spindles.html#migrating-knots-spindles">
3434 Click to read the upgrade guide</a>.
3535 </div>
3636 </details>
···11package types
2233import (
44- "net/url"
55-64 "github.com/bluekeyes/go-gitdiff/gitdiff"
77- "tangled.org/core/appview/filetree"
85)
96107type DiffOpts struct {
118 Split bool `json:"split"`
129}
13101414-func (d DiffOpts) Encode() string {
1515- values := make(url.Values)
1616- if d.Split {
1717- values.Set("diff", "split")
1818- } else {
1919- values.Set("diff", "unified")
2020- }
2121- return values.Encode()
2222-}
2323-2424-// A nicer git diff representation.
2525-type NiceDiff struct {
2626- Commit Commit `json:"commit"`
2727- Stat DiffStat `json:"stat"`
2828- Diff []Diff `json:"diff"`
1111+type TextFragment struct {
1212+ Header string `json:"comment"`
1313+ Lines []gitdiff.Line `json:"lines"`
2914}
30153116type Diff struct {
···4126 IsRename bool `json:"is_rename"`
4227}
43284444-func (d Diff) Stats() DiffFileStat {
4545- var stats DiffFileStat
2929+type DiffStat struct {
3030+ Insertions int64
3131+ Deletions int64
3232+}
3333+3434+func (d *Diff) Stats() DiffStat {
3535+ var stats DiffStat
4636 for _, f := range d.TextFragments {
4737 stats.Insertions += f.LinesAdded
4838 stats.Deletions += f.LinesDeleted
···5040 return stats
5141}
52425353-type DiffStat struct {
5454- Insertions int64 `json:"insertions"`
5555- Deletions int64 `json:"deletions"`
5656- FilesChanged int `json:"files_changed"`
5757-}
5858-5959-type DiffFileStat struct {
6060- Insertions int64
6161- Deletions int64
4343+// A nicer git diff representation.
4444+type NiceDiff struct {
4545+ Commit Commit `json:"commit"`
4646+ Stat struct {
4747+ FilesChanged int `json:"files_changed"`
4848+ Insertions int `json:"insertions"`
4949+ Deletions int `json:"deletions"`
5050+ } `json:"stat"`
5151+ Diff []Diff `json:"diff"`
6252}
63536454type DiffTree struct {
···6858 Diff []*gitdiff.File `json:"diff"`
6959}
70607171-type DiffFileName struct {
7272- Old string
7373- New string
7474-}
7575-7676-func (d NiceDiff) ChangedFiles() []DiffFileRenderer {
7777- drs := make([]DiffFileRenderer, len(d.Diff))
7878- for i, s := range d.Diff {
7979- drs[i] = s
8080- }
8181- return drs
8282-}
6161+func (d *NiceDiff) ChangedFiles() []string {
6262+ files := make([]string, len(d.Diff))
83638484-func (d NiceDiff) FileTree() *filetree.FileTreeNode {
8585- fs := make([]string, len(d.Diff))
8686- for i, s := range d.Diff {
8787- n := s.Names()
8888- if n.New == "" {
8989- fs[i] = n.Old
6464+ for i, f := range d.Diff {
6565+ if f.IsDelete {
6666+ files[i] = f.Name.Old
9067 } else {
9191- fs[i] = n.New
6868+ files[i] = f.Name.New
9269 }
9370 }
9494- return filetree.FileTree(fs)
9595-}
96719797-func (d NiceDiff) Stats() DiffStat {
9898- return d.Stat
7272+ return files
9973}
10074101101-func (d Diff) Id() string {
7575+// used by html elements as a unique ID for hrefs
7676+func (d *Diff) Id() string {
10277 if d.IsDelete {
10378 return d.Name.Old
10479 }
10580 return d.Name.New
10681}
10782108108-func (d Diff) Names() DiffFileName {
109109- var n DiffFileName
110110- if d.IsDelete {
111111- n.Old = d.Name.Old
112112- return n
113113- } else if d.IsCopy || d.IsRename {
114114- n.Old = d.Name.Old
115115- n.New = d.Name.New
116116- return n
117117- } else {
118118- n.New = d.Name.New
119119- return n
120120- }
121121-}
122122-123123-func (d Diff) CanRender() string {
124124- if d.IsBinary {
125125- return "This is a binary file and will not be displayed."
126126- }
127127-128128- return ""
129129-}
130130-131131-func (d Diff) Split() SplitDiff {
8383+func (d *Diff) Split() *SplitDiff {
13284 fragments := make([]SplitFragment, len(d.TextFragments))
13385 for i, fragment := range d.TextFragments {
13486 leftLines, rightLines := SeparateLines(&fragment)
···13991 }
14092 }
14193142142- return SplitDiff{
9494+ return &SplitDiff{
14395 Name: d.Id(),
14496 TextFragments: fragments,
14597 }
-31
types/diff_renderer.go
···11-package types
22-33-import "tangled.org/core/appview/filetree"
44-55-type DiffRenderer interface {
66- // list of file affected by these diffs
77- ChangedFiles() []DiffFileRenderer
88-99- // filetree
1010- FileTree() *filetree.FileTreeNode
1111-1212- Stats() DiffStat
1313-}
1414-1515-type DiffFileRenderer interface {
1616- // html ID for each file in the diff
1717- Id() string
1818-1919- // produce a splitdiff
2020- Split() SplitDiff
2121-2222- // stats for this single file
2323- Stats() DiffFileStat
2424-2525- // old and new name of file
2626- Names() DiffFileName
2727-2828- // whether this diff can be displayed,
2929- // returns a reason if not, and the empty string if it can
3030- CanRender() string
3131-}
···2222 TextFragments []SplitFragment `json:"fragments"`
2323}
24242525-func (d SplitDiff) Id() string {
2525+// used by html elements as a unique ID for hrefs
2626+func (d *SplitDiff) Id() string {
2627 return d.Name
2728}
2829