+36
-28
appview/db/db.go
+36
-28
appview/db/db.go
···
4
4
"context"
5
5
"database/sql"
6
6
"fmt"
7
-
"log"
7
+
"log/slog"
8
8
"reflect"
9
9
"strings"
10
10
11
11
_ "github.com/mattn/go-sqlite3"
12
+
"tangled.org/core/log"
12
13
)
13
14
14
15
type DB struct {
15
16
*sql.DB
17
+
logger *slog.Logger
16
18
}
17
19
18
20
type Execer interface {
···
26
28
PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
27
29
}
28
30
29
-
func Make(dbPath string) (*DB, error) {
31
+
func Make(ctx context.Context, dbPath string) (*DB, error) {
30
32
// https://github.com/mattn/go-sqlite3#connection-string
31
33
opts := []string{
32
34
"_foreign_keys=1",
···
35
37
"_auto_vacuum=incremental",
36
38
}
37
39
40
+
logger := log.FromContext(ctx)
41
+
logger = log.SubLogger(logger, "db")
42
+
38
43
db, err := sql.Open("sqlite3", dbPath+"?"+strings.Join(opts, "&"))
39
44
if err != nil {
40
45
return nil, err
41
46
}
42
-
43
-
ctx := context.Background()
44
47
45
48
conn, err := db.Conn(ctx)
46
49
if err != nil {
···
574
577
}
575
578
576
579
// run migrations
577
-
runMigration(conn, "add-description-to-repos", func(tx *sql.Tx) error {
580
+
runMigration(conn, logger, "add-description-to-repos", func(tx *sql.Tx) error {
578
581
tx.Exec(`
579
582
alter table repos add column description text check (length(description) <= 200);
580
583
`)
581
584
return nil
582
585
})
583
586
584
-
runMigration(conn, "add-rkey-to-pubkeys", func(tx *sql.Tx) error {
587
+
runMigration(conn, logger, "add-rkey-to-pubkeys", func(tx *sql.Tx) error {
585
588
// add unconstrained column
586
589
_, err := tx.Exec(`
587
590
alter table public_keys
···
604
607
return nil
605
608
})
606
609
607
-
runMigration(conn, "add-rkey-to-comments", func(tx *sql.Tx) error {
610
+
runMigration(conn, logger, "add-rkey-to-comments", func(tx *sql.Tx) error {
608
611
_, err := tx.Exec(`
609
612
alter table comments drop column comment_at;
610
613
alter table comments add column rkey text;
···
612
615
return err
613
616
})
614
617
615
-
runMigration(conn, "add-deleted-and-edited-to-issue-comments", func(tx *sql.Tx) error {
618
+
runMigration(conn, logger, "add-deleted-and-edited-to-issue-comments", func(tx *sql.Tx) error {
616
619
_, err := tx.Exec(`
617
620
alter table comments add column deleted text; -- timestamp
618
621
alter table comments add column edited text; -- timestamp
···
620
623
return err
621
624
})
622
625
623
-
runMigration(conn, "add-source-info-to-pulls-and-submissions", func(tx *sql.Tx) error {
626
+
runMigration(conn, logger, "add-source-info-to-pulls-and-submissions", func(tx *sql.Tx) error {
624
627
_, err := tx.Exec(`
625
628
alter table pulls add column source_branch text;
626
629
alter table pulls add column source_repo_at text;
···
629
632
return err
630
633
})
631
634
632
-
runMigration(conn, "add-source-to-repos", func(tx *sql.Tx) error {
635
+
runMigration(conn, logger, "add-source-to-repos", func(tx *sql.Tx) error {
633
636
_, err := tx.Exec(`
634
637
alter table repos add column source text;
635
638
`)
···
641
644
//
642
645
// [0]: https://sqlite.org/pragma.html#pragma_foreign_keys
643
646
conn.ExecContext(ctx, "pragma foreign_keys = off;")
644
-
runMigration(conn, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error {
647
+
runMigration(conn, logger, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error {
645
648
_, err := tx.Exec(`
646
649
create table pulls_new (
647
650
-- identifiers
···
698
701
})
699
702
conn.ExecContext(ctx, "pragma foreign_keys = on;")
700
703
701
-
runMigration(conn, "add-spindle-to-repos", func(tx *sql.Tx) error {
704
+
runMigration(conn, logger, "add-spindle-to-repos", func(tx *sql.Tx) error {
702
705
tx.Exec(`
703
706
alter table repos add column spindle text;
704
707
`)
···
708
711
// drop all knot secrets, add unique constraint to knots
709
712
//
710
713
// knots will henceforth use service auth for signed requests
711
-
runMigration(conn, "no-more-secrets", func(tx *sql.Tx) error {
714
+
runMigration(conn, logger, "no-more-secrets", func(tx *sql.Tx) error {
712
715
_, err := tx.Exec(`
713
716
create table registrations_new (
714
717
id integer primary key autoincrement,
···
731
734
})
732
735
733
736
// recreate and add rkey + created columns with default constraint
734
-
runMigration(conn, "rework-collaborators-table", func(tx *sql.Tx) error {
737
+
runMigration(conn, logger, "rework-collaborators-table", func(tx *sql.Tx) error {
735
738
// create new table
736
739
// - repo_at instead of repo integer
737
740
// - rkey field
···
785
788
return err
786
789
})
787
790
788
-
runMigration(conn, "add-rkey-to-issues", func(tx *sql.Tx) error {
791
+
runMigration(conn, logger, "add-rkey-to-issues", func(tx *sql.Tx) error {
789
792
_, err := tx.Exec(`
790
793
alter table issues add column rkey text not null default '';
791
794
···
797
800
})
798
801
799
802
// repurpose the read-only column to "needs-upgrade"
800
-
runMigration(conn, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error {
803
+
runMigration(conn, logger, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error {
801
804
_, err := tx.Exec(`
802
805
alter table registrations rename column read_only to needs_upgrade;
803
806
`)
···
805
808
})
806
809
807
810
// require all knots to upgrade after the release of total xrpc
808
-
runMigration(conn, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error {
811
+
runMigration(conn, logger, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error {
809
812
_, err := tx.Exec(`
810
813
update registrations set needs_upgrade = 1;
811
814
`)
···
813
816
})
814
817
815
818
// require all knots to upgrade after the release of total xrpc
816
-
runMigration(conn, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error {
819
+
runMigration(conn, logger, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error {
817
820
_, err := tx.Exec(`
818
821
alter table spindles add column needs_upgrade integer not null default 0;
819
822
`)
···
831
834
//
832
835
// disable foreign-keys for the next migration
833
836
conn.ExecContext(ctx, "pragma foreign_keys = off;")
834
-
runMigration(conn, "remove-issue-at-from-issues", func(tx *sql.Tx) error {
837
+
runMigration(conn, logger, "remove-issue-at-from-issues", func(tx *sql.Tx) error {
835
838
_, err := tx.Exec(`
836
839
create table if not exists issues_new (
837
840
-- identifiers
···
901
904
// - new columns
902
905
// * column "reply_to" which can be any other comment
903
906
// * column "at-uri" which is a generated column
904
-
runMigration(conn, "rework-issue-comments", func(tx *sql.Tx) error {
907
+
runMigration(conn, logger, "rework-issue-comments", func(tx *sql.Tx) error {
905
908
_, err := tx.Exec(`
906
909
create table if not exists issue_comments (
907
910
-- identifiers
···
961
964
//
962
965
// disable foreign-keys for the next migration
963
966
conn.ExecContext(ctx, "pragma foreign_keys = off;")
964
-
runMigration(conn, "add-at-uri-to-pulls", func(tx *sql.Tx) error {
967
+
runMigration(conn, logger, "add-at-uri-to-pulls", func(tx *sql.Tx) error {
965
968
_, err := tx.Exec(`
966
969
create table if not exists pulls_new (
967
970
-- identifiers
···
1042
1045
//
1043
1046
// disable foreign-keys for the next migration
1044
1047
conn.ExecContext(ctx, "pragma foreign_keys = off;")
1045
-
runMigration(conn, "remove-repo-at-pull-id-from-pull-submissions", func(tx *sql.Tx) error {
1048
+
runMigration(conn, logger, "remove-repo-at-pull-id-from-pull-submissions", func(tx *sql.Tx) error {
1046
1049
_, err := tx.Exec(`
1047
1050
create table if not exists pull_submissions_new (
1048
1051
-- identifiers
···
1094
1097
})
1095
1098
conn.ExecContext(ctx, "pragma foreign_keys = on;")
1096
1099
1097
-
return &DB{db}, nil
1100
+
return &DB{
1101
+
db,
1102
+
logger,
1103
+
}, nil
1098
1104
}
1099
1105
1100
1106
type migrationFn = func(*sql.Tx) error
1101
1107
1102
-
func runMigration(c *sql.Conn, name string, migrationFn migrationFn) error {
1108
+
func runMigration(c *sql.Conn, logger *slog.Logger, name string, migrationFn migrationFn) error {
1109
+
logger = logger.With("migration", name)
1110
+
1103
1111
tx, err := c.BeginTx(context.Background(), nil)
1104
1112
if err != nil {
1105
1113
return err
···
1116
1124
// run migration
1117
1125
err = migrationFn(tx)
1118
1126
if err != nil {
1119
-
log.Printf("Failed to run migration %s: %v", name, err)
1127
+
logger.Error("failed to run migration", "err", err)
1120
1128
return err
1121
1129
}
1122
1130
1123
1131
// mark migration as complete
1124
1132
_, err = tx.Exec("insert into migrations (name) values (?)", name)
1125
1133
if err != nil {
1126
-
log.Printf("Failed to mark migration %s as complete: %v", name, err)
1134
+
logger.Error("failed to mark migration as complete", "err", err)
1127
1135
return err
1128
1136
}
1129
1137
···
1132
1140
return err
1133
1141
}
1134
1142
1135
-
log.Printf("migration %s applied successfully", name)
1143
+
logger.Info("migration applied successfully")
1136
1144
} else {
1137
-
log.Printf("skipped migration %s, already applied", name)
1145
+
logger.Warn("skipped migration, already applied")
1138
1146
}
1139
1147
1140
1148
return nil
+1
-1
appview/ingester.go
+1
-1
appview/ingester.go
+27
-26
appview/issues/issues.go
+27
-26
appview/issues/issues.go
···
5
5
"database/sql"
6
6
"errors"
7
7
"fmt"
8
-
"log"
9
8
"log/slog"
10
9
"net/http"
11
10
"slices"
···
28
27
"tangled.org/core/appview/reporesolver"
29
28
"tangled.org/core/appview/validator"
30
29
"tangled.org/core/idresolver"
31
-
tlog "tangled.org/core/log"
32
30
"tangled.org/core/tid"
33
31
)
34
32
···
53
51
config *config.Config,
54
52
notifier notify.Notifier,
55
53
validator *validator.Validator,
54
+
logger *slog.Logger,
56
55
) *Issues {
57
56
return &Issues{
58
57
oauth: oauth,
···
62
61
db: db,
63
62
config: config,
64
63
notifier: notifier,
65
-
logger: tlog.New("issues"),
64
+
logger: logger,
66
65
validator: validator,
67
66
}
68
67
}
···
72
71
user := rp.oauth.GetUser(r)
73
72
f, err := rp.repoResolver.Resolve(r)
74
73
if err != nil {
75
-
log.Println("failed to get repo and knot", err)
74
+
l.Error("failed to get repo and knot", "err", err)
76
75
return
77
76
}
78
77
···
99
98
db.FilterContains("scope", tangled.RepoIssueNSID),
100
99
)
101
100
if err != nil {
102
-
log.Println("failed to fetch labels", err)
101
+
l.Error("failed to fetch labels", "err", err)
103
102
rp.pages.Error503(w)
104
103
return
105
104
}
···
126
125
user := rp.oauth.GetUser(r)
127
126
f, err := rp.repoResolver.Resolve(r)
128
127
if err != nil {
129
-
log.Println("failed to get repo and knot", err)
128
+
l.Error("failed to get repo and knot", "err", err)
130
129
return
131
130
}
132
131
···
199
198
200
199
err = db.PutIssue(tx, newIssue)
201
200
if err != nil {
202
-
log.Println("failed to edit issue", err)
201
+
l.Error("failed to edit issue", "err", err)
203
202
rp.pages.Notice(w, "issues", "Failed to edit issue.")
204
203
return
205
204
}
···
237
236
// delete from PDS
238
237
client, err := rp.oauth.AuthorizedClient(r)
239
238
if err != nil {
240
-
log.Println("failed to get authorized client", err)
239
+
l.Error("failed to get authorized client", "err", err)
241
240
rp.pages.Notice(w, "issue-comment", "Failed to delete comment.")
242
241
return
243
242
}
···
282
281
283
282
collaborators, err := f.Collaborators(r.Context())
284
283
if err != nil {
285
-
log.Println("failed to fetch repo collaborators: %w", err)
284
+
l.Error("failed to fetch repo collaborators", "err", err)
286
285
}
287
286
isCollaborator := slices.ContainsFunc(collaborators, func(collab pages.Collaborator) bool {
288
287
return user.Did == collab.Did
···
296
295
db.FilterEq("id", issue.Id),
297
296
)
298
297
if err != nil {
299
-
log.Println("failed to close issue", err)
298
+
l.Error("failed to close issue", "err", err)
300
299
rp.pages.Notice(w, "issue-action", "Failed to close issue. Try again later.")
301
300
return
302
301
}
···
307
306
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId))
308
307
return
309
308
} else {
310
-
log.Println("user is not permitted to close issue")
309
+
l.Error("user is not permitted to close issue")
311
310
http.Error(w, "for biden", http.StatusUnauthorized)
312
311
return
313
312
}
···
318
317
user := rp.oauth.GetUser(r)
319
318
f, err := rp.repoResolver.Resolve(r)
320
319
if err != nil {
321
-
log.Println("failed to get repo and knot", err)
320
+
l.Error("failed to get repo and knot", "err", err)
322
321
return
323
322
}
324
323
···
331
330
332
331
collaborators, err := f.Collaborators(r.Context())
333
332
if err != nil {
334
-
log.Println("failed to fetch repo collaborators: %w", err)
333
+
l.Error("failed to fetch repo collaborators", "err", err)
335
334
}
336
335
isCollaborator := slices.ContainsFunc(collaborators, func(collab pages.Collaborator) bool {
337
336
return user.Did == collab.Did
···
344
343
db.FilterEq("id", issue.Id),
345
344
)
346
345
if err != nil {
347
-
log.Println("failed to reopen issue", err)
346
+
l.Error("failed to reopen issue", "err", err)
348
347
rp.pages.Notice(w, "issue-action", "Failed to reopen issue. Try again later.")
349
348
return
350
349
}
351
350
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId))
352
351
return
353
352
} else {
354
-
log.Println("user is not the owner of the repo")
353
+
l.Error("user is not the owner of the repo")
355
354
http.Error(w, "forbidden", http.StatusUnauthorized)
356
355
return
357
356
}
···
538
537
newBody := r.FormValue("body")
539
538
client, err := rp.oauth.AuthorizedClient(r)
540
539
if err != nil {
541
-
log.Println("failed to get authorized client", err)
540
+
l.Error("failed to get authorized client", "err", err)
542
541
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
543
542
return
544
543
}
···
551
550
552
551
_, err = db.AddIssueComment(rp.db, newComment)
553
552
if err != nil {
554
-
log.Println("failed to perferom update-description query", err)
553
+
l.Error("failed to perferom update-description query", "err", err)
555
554
rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.")
556
555
return
557
556
}
···
561
560
// update the record on pds
562
561
ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueCommentNSID, user.Did, comment.Rkey)
563
562
if err != nil {
564
-
log.Println("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey)
563
+
l.Error("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey)
565
564
rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "Failed to update description, no record found on PDS.")
566
565
return
567
566
}
···
729
728
if comment.Rkey != "" {
730
729
client, err := rp.oauth.AuthorizedClient(r)
731
730
if err != nil {
732
-
log.Println("failed to get authorized client", err)
731
+
l.Error("failed to get authorized client", "err", err)
733
732
rp.pages.Notice(w, "issue-comment", "Failed to delete comment.")
734
733
return
735
734
}
···
739
738
Rkey: comment.Rkey,
740
739
})
741
740
if err != nil {
742
-
log.Println(err)
741
+
l.Error("failed to delete from PDS", "err", err)
743
742
}
744
743
}
745
744
···
757
756
}
758
757
759
758
func (rp *Issues) RepoIssues(w http.ResponseWriter, r *http.Request) {
759
+
l := rp.logger.With("handler", "RepoIssues")
760
+
760
761
params := r.URL.Query()
761
762
state := params.Get("state")
762
763
isOpen := true
···
771
772
772
773
page, ok := r.Context().Value("page").(pagination.Page)
773
774
if !ok {
774
-
log.Println("failed to get page")
775
+
l.Error("failed to get page")
775
776
page = pagination.FirstPage()
776
777
}
777
778
778
779
user := rp.oauth.GetUser(r)
779
780
f, err := rp.repoResolver.Resolve(r)
780
781
if err != nil {
781
-
log.Println("failed to get repo and knot", err)
782
+
l.Error("failed to get repo and knot", "err", err)
782
783
return
783
784
}
784
785
···
793
794
db.FilterEq("open", openVal),
794
795
)
795
796
if err != nil {
796
-
log.Println("failed to get issues", err)
797
+
l.Error("failed to get issues", "err", err)
797
798
rp.pages.Notice(w, "issues", "Failed to load issues. Try again later.")
798
799
return
799
800
}
···
804
805
db.FilterContains("scope", tangled.RepoIssueNSID),
805
806
)
806
807
if err != nil {
807
-
log.Println("failed to fetch labels", err)
808
+
l.Error("failed to fetch labels", "err", err)
808
809
rp.pages.Error503(w)
809
810
return
810
811
}
···
901
902
902
903
err = db.PutIssue(tx, issue)
903
904
if err != nil {
904
-
log.Println("failed to create issue", err)
905
+
l.Error("failed to create issue", "err", err)
905
906
rp.pages.Notice(w, "issues", "Failed to create issue.")
906
907
return
907
908
}
908
909
909
910
if err = tx.Commit(); err != nil {
910
-
log.Println("failed to create issue", err)
911
+
l.Error("failed to create issue", "err", err)
911
912
rp.pages.Notice(w, "issues", "Failed to create issue.")
912
913
return
913
914
}
+1
-3
appview/labels/labels.go
+1
-3
appview/labels/labels.go
···
16
16
"tangled.org/core/appview/oauth"
17
17
"tangled.org/core/appview/pages"
18
18
"tangled.org/core/appview/validator"
19
-
"tangled.org/core/log"
20
19
"tangled.org/core/rbac"
21
20
"tangled.org/core/tid"
22
21
···
42
41
db *db.DB,
43
42
validator *validator.Validator,
44
43
enforcer *rbac.Enforcer,
44
+
logger *slog.Logger,
45
45
) *Labels {
46
-
logger := log.New("labels")
47
-
48
46
return &Labels{
49
47
oauth: oauth,
50
48
pages: pages,
+15
-12
appview/notifications/notifications.go
+15
-12
appview/notifications/notifications.go
···
1
1
package notifications
2
2
3
3
import (
4
-
"log"
4
+
"log/slog"
5
5
"net/http"
6
6
"strconv"
7
7
···
14
14
)
15
15
16
16
type Notifications struct {
17
-
db *db.DB
18
-
oauth *oauth.OAuth
19
-
pages *pages.Pages
17
+
db *db.DB
18
+
oauth *oauth.OAuth
19
+
pages *pages.Pages
20
+
logger *slog.Logger
20
21
}
21
22
22
-
func New(database *db.DB, oauthHandler *oauth.OAuth, pagesHandler *pages.Pages) *Notifications {
23
+
func New(database *db.DB, oauthHandler *oauth.OAuth, pagesHandler *pages.Pages, logger *slog.Logger) *Notifications {
23
24
return &Notifications{
24
-
db: database,
25
-
oauth: oauthHandler,
26
-
pages: pagesHandler,
25
+
db: database,
26
+
oauth: oauthHandler,
27
+
pages: pagesHandler,
28
+
logger: logger,
27
29
}
28
30
}
29
31
···
44
46
}
45
47
46
48
func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request) {
49
+
l := n.logger.With("handler", "notificationsPage")
47
50
user := n.oauth.GetUser(r)
48
51
49
52
page, ok := r.Context().Value("page").(pagination.Page)
50
53
if !ok {
51
-
log.Println("failed to get page")
54
+
l.Error("failed to get page")
52
55
page = pagination.FirstPage()
53
56
}
54
57
···
57
60
db.FilterEq("recipient_did", user.Did),
58
61
)
59
62
if err != nil {
60
-
log.Println("failed to get total notifications:", err)
63
+
l.Error("failed to get total notifications", "err", err)
61
64
n.pages.Error500(w)
62
65
return
63
66
}
···
68
71
db.FilterEq("recipient_did", user.Did),
69
72
)
70
73
if err != nil {
71
-
log.Println("failed to get notifications:", err)
74
+
l.Error("failed to get notifications", "err", err)
72
75
n.pages.Error500(w)
73
76
return
74
77
}
75
78
76
79
err = n.db.MarkAllNotificationsRead(r.Context(), user.Did)
77
80
if err != nil {
78
-
log.Println("failed to mark notifications as read:", err)
81
+
l.Error("failed to mark notifications as read", "err", err)
79
82
}
80
83
81
84
unreadCount := 0
+2
-2
appview/pages/pages.go
+2
-2
appview/pages/pages.go
···
54
54
logger *slog.Logger
55
55
}
56
56
57
-
func NewPages(config *config.Config, res *idresolver.Resolver) *Pages {
57
+
func NewPages(config *config.Config, res *idresolver.Resolver, logger *slog.Logger) *Pages {
58
58
// initialized with safe defaults, can be overriden per use
59
59
rctx := &markup.RenderContext{
60
60
IsDev: config.Core.Dev,
···
72
72
rctx: rctx,
73
73
resolver: res,
74
74
templateDir: "appview/pages",
75
-
logger: slog.Default().With("component", "pages"),
75
+
logger: logger,
76
76
}
77
77
78
78
if p.dev {
+1
-3
appview/pipelines/pipelines.go
+1
-3
appview/pipelines/pipelines.go
···
16
16
"tangled.org/core/appview/reporesolver"
17
17
"tangled.org/core/eventconsumer"
18
18
"tangled.org/core/idresolver"
19
-
"tangled.org/core/log"
20
19
"tangled.org/core/rbac"
21
20
spindlemodel "tangled.org/core/spindle/models"
22
21
···
45
44
db *db.DB,
46
45
config *config.Config,
47
46
enforcer *rbac.Enforcer,
47
+
logger *slog.Logger,
48
48
) *Pipelines {
49
-
logger := log.New("pipelines")
50
-
51
49
return &Pipelines{
52
50
oauth: oauth,
53
51
repoResolver: repoResolver,
+4
appview/pulls/pulls.go
+4
appview/pulls/pulls.go
···
6
6
"errors"
7
7
"fmt"
8
8
"log"
9
+
"log/slog"
9
10
"net/http"
10
11
"slices"
11
12
"sort"
···
46
47
config *config.Config
47
48
notifier notify.Notifier
48
49
enforcer *rbac.Enforcer
50
+
logger *slog.Logger
49
51
}
50
52
51
53
func New(
···
57
59
config *config.Config,
58
60
notifier notify.Notifier,
59
61
enforcer *rbac.Enforcer,
62
+
logger *slog.Logger,
60
63
) *Pulls {
61
64
return &Pulls{
62
65
oauth: oauth,
···
67
70
config: config,
68
71
notifier: notifier,
69
72
enforcer: enforcer,
73
+
logger: logger,
70
74
}
71
75
}
72
76
+14
-11
appview/repo/index.go
+14
-11
appview/repo/index.go
···
3
3
import (
4
4
"errors"
5
5
"fmt"
6
-
"log"
6
+
"log/slog"
7
7
"net/http"
8
8
"net/url"
9
9
"slices"
···
31
31
)
32
32
33
33
func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) {
34
+
l := rp.logger.With("handler", "RepoIndex")
35
+
34
36
ref := chi.URLParam(r, "ref")
35
37
ref, _ = url.PathUnescape(ref)
36
38
37
39
f, err := rp.repoResolver.Resolve(r)
38
40
if err != nil {
39
-
log.Println("failed to fully resolve repo", err)
41
+
l.Error("failed to fully resolve repo", "err", err)
40
42
return
41
43
}
42
44
···
56
58
result, err := rp.buildIndexResponse(r.Context(), xrpcc, f, ref)
57
59
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
58
60
if errors.Is(xrpcerr, xrpcclient.ErrXrpcUnsupported) {
59
-
log.Println("failed to call XRPC repo.index", err)
61
+
l.Error("failed to call XRPC repo.index", "err", err)
60
62
rp.pages.RepoIndexPage(w, pages.RepoIndexParams{
61
63
LoggedInUser: user,
62
64
NeedsKnotUpgrade: true,
···
66
68
}
67
69
68
70
rp.pages.Error503(w)
69
-
log.Println("failed to build index response", err)
71
+
l.Error("failed to build index response", "err", err)
70
72
return
71
73
}
72
74
···
119
121
emails := uniqueEmails(commitsTrunc)
120
122
emailToDidMap, err := db.GetEmailToDid(rp.db, emails, true)
121
123
if err != nil {
122
-
log.Println("failed to get email to did map", err)
124
+
l.Error("failed to get email to did map", "err", err)
123
125
}
124
126
125
127
vc, err := commitverify.GetVerifiedObjectCommits(rp.db, emailToDidMap, commitsTrunc)
126
128
if err != nil {
127
-
log.Println(err)
129
+
l.Error("failed to GetVerifiedObjectCommits", "err", err)
128
130
}
129
131
130
132
// TODO: a bit dirty
131
-
languageInfo, err := rp.getLanguageInfo(r.Context(), f, xrpcc, result.Ref, ref == "")
133
+
languageInfo, err := rp.getLanguageInfo(r.Context(), l, f, xrpcc, result.Ref, ref == "")
132
134
if err != nil {
133
-
log.Printf("failed to compute language percentages: %s", err)
135
+
l.Warn("failed to compute language percentages", "err", err)
134
136
// non-fatal
135
137
}
136
138
···
140
142
}
141
143
pipelines, err := getPipelineStatuses(rp.db, repoInfo, shas)
142
144
if err != nil {
143
-
log.Printf("failed to fetch pipeline statuses: %s", err)
145
+
l.Error("failed to fetch pipeline statuses", "err", err)
144
146
// non-fatal
145
147
}
146
148
···
162
164
163
165
func (rp *Repo) getLanguageInfo(
164
166
ctx context.Context,
167
+
l *slog.Logger,
165
168
f *reporesolver.ResolvedRepo,
166
169
xrpcc *indigoxrpc.Client,
167
170
currentRef string,
···
180
183
ls, err := tangled.RepoLanguages(ctx, xrpcc, currentRef, repo)
181
184
if err != nil {
182
185
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
183
-
log.Println("failed to call XRPC repo.languages", xrpcerr)
186
+
l.Error("failed to call XRPC repo.languages", "err", xrpcerr)
184
187
return nil, xrpcerr
185
188
}
186
189
return nil, err
···
210
213
err = db.UpdateRepoLanguages(tx, f.RepoAt(), currentRef, langs)
211
214
if err != nil {
212
215
// non-fatal
213
-
log.Println("failed to cache lang results", err)
216
+
l.Error("failed to cache lang results", "err", err)
214
217
}
215
218
216
219
err = tx.Commit()
+130
-92
appview/repo/repo.go
+130
-92
appview/repo/repo.go
···
7
7
"errors"
8
8
"fmt"
9
9
"io"
10
-
"log"
11
10
"log/slog"
12
11
"net/http"
13
12
"net/url"
···
90
89
}
91
90
92
91
func (rp *Repo) DownloadArchive(w http.ResponseWriter, r *http.Request) {
92
+
l := rp.logger.With("handler", "DownloadArchive")
93
+
93
94
ref := chi.URLParam(r, "ref")
94
95
ref, _ = url.PathUnescape(ref)
95
96
96
97
f, err := rp.repoResolver.Resolve(r)
97
98
if err != nil {
98
-
log.Println("failed to get repo and knot", err)
99
+
l.Error("failed to get repo and knot", "err", err)
99
100
return
100
101
}
101
102
···
111
112
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
112
113
archiveBytes, err := tangled.RepoArchive(r.Context(), xrpcc, "tar.gz", "", ref, repo)
113
114
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
114
-
log.Println("failed to call XRPC repo.archive", xrpcerr)
115
+
l.Error("failed to call XRPC repo.archive", "err", xrpcerr)
115
116
rp.pages.Error503(w)
116
117
return
117
118
}
···
128
129
}
129
130
130
131
func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) {
132
+
l := rp.logger.With("handler", "RepoLog")
133
+
131
134
f, err := rp.repoResolver.Resolve(r)
132
135
if err != nil {
133
-
log.Println("failed to fully resolve repo", err)
136
+
l.Error("failed to fully resolve repo", "err", err)
134
137
return
135
138
}
136
139
···
165
168
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
166
169
xrpcBytes, err := tangled.RepoLog(r.Context(), xrpcc, cursor, limit, "", ref, repo)
167
170
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
168
-
log.Println("failed to call XRPC repo.log", xrpcerr)
171
+
l.Error("failed to call XRPC repo.log", "err", xrpcerr)
169
172
rp.pages.Error503(w)
170
173
return
171
174
}
172
175
173
176
var xrpcResp types.RepoLogResponse
174
177
if err := json.Unmarshal(xrpcBytes, &xrpcResp); err != nil {
175
-
log.Println("failed to decode XRPC response", err)
178
+
l.Error("failed to decode XRPC response", "err", err)
176
179
rp.pages.Error503(w)
177
180
return
178
181
}
179
182
180
183
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
181
184
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
182
-
log.Println("failed to call XRPC repo.tags", xrpcerr)
185
+
l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
183
186
rp.pages.Error503(w)
184
187
return
185
188
}
···
196
199
197
200
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
198
201
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
199
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
202
+
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
200
203
rp.pages.Error503(w)
201
204
return
202
205
}
···
214
217
215
218
emailToDidMap, err := db.GetEmailToDid(rp.db, uniqueEmails(xrpcResp.Commits), true)
216
219
if err != nil {
217
-
log.Println("failed to fetch email to did mapping", err)
220
+
l.Error("failed to fetch email to did mapping", "err", err)
218
221
}
219
222
220
223
vc, err := commitverify.GetVerifiedObjectCommits(rp.db, emailToDidMap, xrpcResp.Commits)
221
224
if err != nil {
222
-
log.Println(err)
225
+
l.Error("failed to GetVerifiedObjectCommits", "err", err)
223
226
}
224
227
225
228
repoInfo := f.RepoInfo(user)
···
230
233
}
231
234
pipelines, err := getPipelineStatuses(rp.db, repoInfo, shas)
232
235
if err != nil {
233
-
log.Println(err)
236
+
l.Error("failed to getPipelineStatuses", "err", err)
234
237
// non-fatal
235
238
}
236
239
···
246
249
}
247
250
248
251
func (rp *Repo) RepoDescriptionEdit(w http.ResponseWriter, r *http.Request) {
252
+
l := rp.logger.With("handler", "RepoDescriptionEdit")
253
+
249
254
f, err := rp.repoResolver.Resolve(r)
250
255
if err != nil {
251
-
log.Println("failed to get repo and knot", err)
256
+
l.Error("failed to get repo and knot", "err", err)
252
257
w.WriteHeader(http.StatusBadRequest)
253
258
return
254
259
}
···
260
265
}
261
266
262
267
func (rp *Repo) RepoDescription(w http.ResponseWriter, r *http.Request) {
268
+
l := rp.logger.With("handler", "RepoDescription")
269
+
263
270
f, err := rp.repoResolver.Resolve(r)
264
271
if err != nil {
265
-
log.Println("failed to get repo and knot", err)
272
+
l.Error("failed to get repo and knot", "err", err)
266
273
w.WriteHeader(http.StatusBadRequest)
267
274
return
268
275
}
···
270
277
repoAt := f.RepoAt()
271
278
rkey := repoAt.RecordKey().String()
272
279
if rkey == "" {
273
-
log.Println("invalid aturi for repo", err)
280
+
l.Error("invalid aturi for repo", "err", err)
274
281
w.WriteHeader(http.StatusInternalServerError)
275
282
return
276
283
}
···
287
294
newDescription := r.FormValue("description")
288
295
client, err := rp.oauth.AuthorizedClient(r)
289
296
if err != nil {
290
-
log.Println("failed to get client")
297
+
l.Error("failed to get client")
291
298
rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.")
292
299
return
293
300
}
···
295
302
// optimistic update
296
303
err = db.UpdateDescription(rp.db, string(repoAt), newDescription)
297
304
if err != nil {
298
-
log.Println("failed to perferom update-description query", err)
305
+
l.Error("failed to perform update-description query", "err", err)
299
306
rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.")
300
307
return
301
308
}
···
324
331
})
325
332
326
333
if err != nil {
327
-
log.Println("failed to perferom update-description query", err)
334
+
l.Error("failed to perferom update-description query", "err", err)
328
335
// failed to get record
329
336
rp.pages.Notice(w, "repo-notice", "Failed to update description, unable to save to PDS.")
330
337
return
···
341
348
}
342
349
343
350
func (rp *Repo) RepoCommit(w http.ResponseWriter, r *http.Request) {
351
+
l := rp.logger.With("handler", "RepoCommit")
352
+
344
353
f, err := rp.repoResolver.Resolve(r)
345
354
if err != nil {
346
-
log.Println("failed to fully resolve repo", err)
355
+
l.Error("failed to fully resolve repo", "err", err)
347
356
return
348
357
}
349
358
ref := chi.URLParam(r, "ref")
···
371
380
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
372
381
xrpcBytes, err := tangled.RepoDiff(r.Context(), xrpcc, ref, repo)
373
382
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
374
-
log.Println("failed to call XRPC repo.diff", xrpcerr)
383
+
l.Error("failed to call XRPC repo.diff", "err", xrpcerr)
375
384
rp.pages.Error503(w)
376
385
return
377
386
}
378
387
379
388
var result types.RepoCommitResponse
380
389
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
381
-
log.Println("failed to decode XRPC response", err)
390
+
l.Error("failed to decode XRPC response", "err", err)
382
391
rp.pages.Error503(w)
383
392
return
384
393
}
385
394
386
395
emailToDidMap, err := db.GetEmailToDid(rp.db, []string{result.Diff.Commit.Committer.Email, result.Diff.Commit.Author.Email}, true)
387
396
if err != nil {
388
-
log.Println("failed to get email to did mapping:", err)
397
+
l.Error("failed to get email to did mapping", "err", err)
389
398
}
390
399
391
400
vc, err := commitverify.GetVerifiedCommits(rp.db, emailToDidMap, []types.NiceDiff{*result.Diff})
392
401
if err != nil {
393
-
log.Println(err)
402
+
l.Error("failed to GetVerifiedCommits", "err", err)
394
403
}
395
404
396
405
user := rp.oauth.GetUser(r)
397
406
repoInfo := f.RepoInfo(user)
398
407
pipelines, err := getPipelineStatuses(rp.db, repoInfo, []string{result.Diff.Commit.This})
399
408
if err != nil {
400
-
log.Println(err)
409
+
l.Error("failed to getPipelineStatuses", "err", err)
401
410
// non-fatal
402
411
}
403
412
var pipeline *models.Pipeline
···
417
426
}
418
427
419
428
func (rp *Repo) RepoTree(w http.ResponseWriter, r *http.Request) {
429
+
l := rp.logger.With("handler", "RepoTree")
430
+
420
431
f, err := rp.repoResolver.Resolve(r)
421
432
if err != nil {
422
-
log.Println("failed to fully resolve repo", err)
433
+
l.Error("failed to fully resolve repo", "err", err)
423
434
return
424
435
}
425
436
···
444
455
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
445
456
xrpcResp, err := tangled.RepoTree(r.Context(), xrpcc, treePath, ref, repo)
446
457
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
447
-
log.Println("failed to call XRPC repo.tree", xrpcerr)
458
+
l.Error("failed to call XRPC repo.tree", "err", xrpcerr)
448
459
rp.pages.Error503(w)
449
460
return
450
461
}
···
519
530
}
520
531
521
532
func (rp *Repo) RepoTags(w http.ResponseWriter, r *http.Request) {
533
+
l := rp.logger.With("handler", "RepoTags")
534
+
522
535
f, err := rp.repoResolver.Resolve(r)
523
536
if err != nil {
524
-
log.Println("failed to get repo and knot", err)
537
+
l.Error("failed to get repo and knot", "err", err)
525
538
return
526
539
}
527
540
···
537
550
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
538
551
xrpcBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
539
552
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
540
-
log.Println("failed to call XRPC repo.tags", xrpcerr)
553
+
l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
541
554
rp.pages.Error503(w)
542
555
return
543
556
}
544
557
545
558
var result types.RepoTagsResponse
546
559
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
547
-
log.Println("failed to decode XRPC response", err)
560
+
l.Error("failed to decode XRPC response", "err", err)
548
561
rp.pages.Error503(w)
549
562
return
550
563
}
551
564
552
565
artifacts, err := db.GetArtifact(rp.db, db.FilterEq("repo_at", f.RepoAt()))
553
566
if err != nil {
554
-
log.Println("failed grab artifacts", err)
567
+
l.Error("failed grab artifacts", "err", err)
555
568
return
556
569
}
557
570
···
588
601
}
589
602
590
603
func (rp *Repo) RepoBranches(w http.ResponseWriter, r *http.Request) {
604
+
l := rp.logger.With("handler", "RepoBranches")
605
+
591
606
f, err := rp.repoResolver.Resolve(r)
592
607
if err != nil {
593
-
log.Println("failed to get repo and knot", err)
608
+
l.Error("failed to get repo and knot", "err", err)
594
609
return
595
610
}
596
611
···
606
621
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
607
622
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
608
623
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
609
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
624
+
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
610
625
rp.pages.Error503(w)
611
626
return
612
627
}
613
628
614
629
var result types.RepoBranchesResponse
615
630
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
616
-
log.Println("failed to decode XRPC response", err)
631
+
l.Error("failed to decode XRPC response", "err", err)
617
632
rp.pages.Error503(w)
618
633
return
619
634
}
···
629
644
}
630
645
631
646
func (rp *Repo) DeleteBranch(w http.ResponseWriter, r *http.Request) {
647
+
l := rp.logger.With("handler", "DeleteBranch")
648
+
632
649
f, err := rp.repoResolver.Resolve(r)
633
650
if err != nil {
634
-
log.Println("failed to get repo and knot", err)
651
+
l.Error("failed to get repo and knot", "err", err)
635
652
return
636
653
}
637
654
638
655
noticeId := "delete-branch-error"
639
656
fail := func(msg string, err error) {
640
-
log.Println(msg, "err", err)
657
+
l.Error(msg, "err", err)
641
658
rp.pages.Notice(w, noticeId, msg)
642
659
}
643
660
···
670
687
fail(fmt.Sprintf("Failed to delete branch: %s", err), err)
671
688
return
672
689
}
673
-
log.Println("deleted branch from knot", "branch", branch, "repo", f.RepoAt())
690
+
l.Error("deleted branch from knot", "branch", branch, "repo", f.RepoAt())
674
691
675
692
rp.pages.HxRefresh(w)
676
693
}
677
694
678
695
func (rp *Repo) RepoBlob(w http.ResponseWriter, r *http.Request) {
696
+
l := rp.logger.With("handler", "RepoBlob")
697
+
679
698
f, err := rp.repoResolver.Resolve(r)
680
699
if err != nil {
681
-
log.Println("failed to get repo and knot", err)
700
+
l.Error("failed to get repo and knot", "err", err)
682
701
return
683
702
}
684
703
···
700
719
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Repo.Name)
701
720
resp, err := tangled.RepoBlob(r.Context(), xrpcc, filePath, false, ref, repo)
702
721
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
703
-
log.Println("failed to call XRPC repo.blob", xrpcerr)
722
+
l.Error("failed to call XRPC repo.blob", "err", xrpcerr)
704
723
rp.pages.Error503(w)
705
724
return
706
725
}
···
800
819
}
801
820
802
821
func (rp *Repo) RepoBlobRaw(w http.ResponseWriter, r *http.Request) {
822
+
l := rp.logger.With("handler", "RepoBlobRaw")
823
+
803
824
f, err := rp.repoResolver.Resolve(r)
804
825
if err != nil {
805
-
log.Println("failed to get repo and knot", err)
826
+
l.Error("failed to get repo and knot", err)
806
827
w.WriteHeader(http.StatusBadRequest)
807
828
return
808
829
}
···
834
855
835
856
req, err := http.NewRequest("GET", blobURL, nil)
836
857
if err != nil {
837
-
log.Println("failed to create request", err)
858
+
l.Error("failed to create request", "err", err)
838
859
return
839
860
}
840
861
···
846
867
client := &http.Client{}
847
868
resp, err := client.Do(req)
848
869
if err != nil {
849
-
log.Println("failed to reach knotserver", err)
870
+
l.Error("failed to reach knotserver", "err", err)
850
871
rp.pages.Error503(w)
851
872
return
852
873
}
···
859
880
}
860
881
861
882
if resp.StatusCode != http.StatusOK {
862
-
log.Printf("knotserver returned non-OK status for raw blob %s: %d", blobURL, resp.StatusCode)
883
+
l.Error("knotserver returned non-OK status for raw blob", "url", blobURL, "statuscode", resp.StatusCode)
863
884
w.WriteHeader(resp.StatusCode)
864
885
_, _ = io.Copy(w, resp.Body)
865
886
return
···
868
889
contentType := resp.Header.Get("Content-Type")
869
890
body, err := io.ReadAll(resp.Body)
870
891
if err != nil {
871
-
log.Printf("error reading response body from knotserver: %v", err)
892
+
l.Error("error reading response body from knotserver", "err", err)
872
893
w.WriteHeader(http.StatusInternalServerError)
873
894
return
874
895
}
···
1443
1464
db.FilterContains("scope", subject.Collection().String()),
1444
1465
)
1445
1466
if err != nil {
1446
-
log.Println("failed to fetch label defs", err)
1467
+
l.Error("failed to fetch label defs", "err", err)
1447
1468
return
1448
1469
}
1449
1470
···
1454
1475
1455
1476
states, err := db.GetLabels(rp.db, db.FilterEq("subject", subject))
1456
1477
if err != nil {
1457
-
log.Println("failed to build label state", err)
1478
+
l.Error("failed to build label state", "err", err)
1458
1479
return
1459
1480
}
1460
1481
state := states[subject]
···
1491
1512
db.FilterContains("scope", subject.Collection().String()),
1492
1513
)
1493
1514
if err != nil {
1494
-
log.Println("failed to fetch labels", err)
1515
+
l.Error("failed to fetch labels", "err", err)
1495
1516
return
1496
1517
}
1497
1518
···
1502
1523
1503
1524
states, err := db.GetLabels(rp.db, db.FilterEq("subject", subject))
1504
1525
if err != nil {
1505
-
log.Println("failed to build label state", err)
1526
+
l.Error("failed to build label state", "err", err)
1506
1527
return
1507
1528
}
1508
1529
state := states[subject]
···
1649
1670
1650
1671
func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) {
1651
1672
user := rp.oauth.GetUser(r)
1673
+
l := rp.logger.With("handler", "DeleteRepo")
1652
1674
1653
1675
noticeId := "operation-error"
1654
1676
f, err := rp.repoResolver.Resolve(r)
1655
1677
if err != nil {
1656
-
log.Println("failed to get repo and knot", err)
1678
+
l.Error("failed to get repo and knot", "err", err)
1657
1679
return
1658
1680
}
1659
1681
1660
1682
// remove record from pds
1661
1683
atpClient, err := rp.oauth.AuthorizedClient(r)
1662
1684
if err != nil {
1663
-
log.Println("failed to get authorized client", err)
1685
+
l.Error("failed to get authorized client", "err", err)
1664
1686
return
1665
1687
}
1666
1688
_, err = comatproto.RepoDeleteRecord(r.Context(), atpClient, &comatproto.RepoDeleteRecord_Input{
···
1669
1691
Rkey: f.Rkey,
1670
1692
})
1671
1693
if err != nil {
1672
-
log.Printf("failed to delete record: %s", err)
1694
+
l.Error("failed to delete record", "err", err)
1673
1695
rp.pages.Notice(w, noticeId, "Failed to delete repository from PDS.")
1674
1696
return
1675
1697
}
1676
-
log.Println("removed repo record ", f.RepoAt().String())
1698
+
l.Info("removed repo record", "aturi", f.RepoAt().String())
1677
1699
1678
1700
client, err := rp.oauth.ServiceClient(
1679
1701
r,
···
1682
1704
oauth.WithDev(rp.config.Core.Dev),
1683
1705
)
1684
1706
if err != nil {
1685
-
log.Println("failed to connect to knot server:", err)
1707
+
l.Error("failed to connect to knot server", "err", err)
1686
1708
return
1687
1709
}
1688
1710
···
1699
1721
rp.pages.Notice(w, noticeId, err.Error())
1700
1722
return
1701
1723
}
1702
-
log.Println("deleted repo from knot")
1724
+
l.Info("deleted repo from knot")
1703
1725
1704
1726
tx, err := rp.db.BeginTx(r.Context(), nil)
1705
1727
if err != nil {
1706
-
log.Println("failed to start tx")
1728
+
l.Error("failed to start tx")
1707
1729
w.Write(fmt.Append(nil, "failed to add collaborator: ", err))
1708
1730
return
1709
1731
}
···
1711
1733
tx.Rollback()
1712
1734
err = rp.enforcer.E.LoadPolicy()
1713
1735
if err != nil {
1714
-
log.Println("failed to rollback policies")
1736
+
l.Error("failed to rollback policies")
1715
1737
}
1716
1738
}()
1717
1739
···
1725
1747
did := c[0]
1726
1748
rp.enforcer.RemoveCollaborator(did, f.Knot, f.DidSlashRepo())
1727
1749
}
1728
-
log.Println("removed collaborators")
1750
+
l.Info("removed collaborators")
1729
1751
1730
1752
// remove repo RBAC
1731
1753
err = rp.enforcer.RemoveRepo(f.OwnerDid(), f.Knot, f.DidSlashRepo())
···
1740
1762
rp.pages.Notice(w, noticeId, "Failed to update appview")
1741
1763
return
1742
1764
}
1743
-
log.Println("removed repo from db")
1765
+
l.Info("removed repo from db")
1744
1766
1745
1767
err = tx.Commit()
1746
1768
if err != nil {
1747
-
log.Println("failed to commit changes", err)
1769
+
l.Error("failed to commit changes", "err", err)
1748
1770
http.Error(w, err.Error(), http.StatusInternalServerError)
1749
1771
return
1750
1772
}
1751
1773
1752
1774
err = rp.enforcer.E.SavePolicy()
1753
1775
if err != nil {
1754
-
log.Println("failed to update ACLs", err)
1776
+
l.Error("failed to update ACLs", "err", err)
1755
1777
http.Error(w, err.Error(), http.StatusInternalServerError)
1756
1778
return
1757
1779
}
···
1760
1782
}
1761
1783
1762
1784
func (rp *Repo) SetDefaultBranch(w http.ResponseWriter, r *http.Request) {
1785
+
l := rp.logger.With("handler", "SetDefaultBranch")
1786
+
1763
1787
f, err := rp.repoResolver.Resolve(r)
1764
1788
if err != nil {
1765
-
log.Println("failed to get repo and knot", err)
1789
+
l.Error("failed to get repo and knot", "err", err)
1766
1790
return
1767
1791
}
1768
1792
···
1780
1804
oauth.WithDev(rp.config.Core.Dev),
1781
1805
)
1782
1806
if err != nil {
1783
-
log.Println("failed to connect to knot server:", err)
1807
+
l.Error("failed to connect to knot server", "err", err)
1784
1808
rp.pages.Notice(w, noticeId, "Failed to connect to knot server.")
1785
1809
return
1786
1810
}
···
1794
1818
},
1795
1819
)
1796
1820
if err := xrpcclient.HandleXrpcErr(xe); err != nil {
1797
-
log.Println("xrpc failed", "err", xe)
1821
+
l.Error("xrpc failed", "err", xe)
1798
1822
rp.pages.Notice(w, noticeId, err.Error())
1799
1823
return
1800
1824
}
···
1809
1833
1810
1834
f, err := rp.repoResolver.Resolve(r)
1811
1835
if err != nil {
1812
-
log.Println("failed to get repo and knot", err)
1836
+
l.Error("failed to get repo and knot", "err", err)
1813
1837
return
1814
1838
}
1815
1839
1816
1840
if f.Spindle == "" {
1817
-
log.Println("empty spindle cannot add/rm secret", err)
1841
+
l.Error("empty spindle cannot add/rm secret", "err", err)
1818
1842
return
1819
1843
}
1820
1844
···
1831
1855
oauth.WithDev(rp.config.Core.Dev),
1832
1856
)
1833
1857
if err != nil {
1834
-
log.Println("failed to create spindle client", err)
1858
+
l.Error("failed to create spindle client", "err", err)
1835
1859
return
1836
1860
}
1837
1861
···
1917
1941
}
1918
1942
1919
1943
func (rp *Repo) generalSettings(w http.ResponseWriter, r *http.Request) {
1944
+
l := rp.logger.With("handler", "generalSettings")
1945
+
1920
1946
f, err := rp.repoResolver.Resolve(r)
1921
1947
user := rp.oauth.GetUser(r)
1922
1948
···
1932
1958
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
1933
1959
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
1934
1960
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1935
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
1961
+
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
1936
1962
rp.pages.Error503(w)
1937
1963
return
1938
1964
}
1939
1965
1940
1966
var result types.RepoBranchesResponse
1941
1967
if err := json.Unmarshal(xrpcBytes, &result); err != nil {
1942
-
log.Println("failed to decode XRPC response", err)
1968
+
l.Error("failed to decode XRPC response", "err", err)
1943
1969
rp.pages.Error503(w)
1944
1970
return
1945
1971
}
1946
1972
1947
1973
defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", models.DefaultLabelDefs()))
1948
1974
if err != nil {
1949
-
log.Println("failed to fetch labels", err)
1975
+
l.Error("failed to fetch labels", "err", err)
1950
1976
rp.pages.Error503(w)
1951
1977
return
1952
1978
}
1953
1979
1954
1980
labels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", f.Repo.Labels))
1955
1981
if err != nil {
1956
-
log.Println("failed to fetch labels", err)
1982
+
l.Error("failed to fetch labels", "err", err)
1957
1983
rp.pages.Error503(w)
1958
1984
return
1959
1985
}
···
2001
2027
}
2002
2028
2003
2029
func (rp *Repo) accessSettings(w http.ResponseWriter, r *http.Request) {
2030
+
l := rp.logger.With("handler", "accessSettings")
2031
+
2004
2032
f, err := rp.repoResolver.Resolve(r)
2005
2033
user := rp.oauth.GetUser(r)
2006
2034
2007
2035
repoCollaborators, err := f.Collaborators(r.Context())
2008
2036
if err != nil {
2009
-
log.Println("failed to get collaborators", err)
2037
+
l.Error("failed to get collaborators", "err", err)
2010
2038
}
2011
2039
2012
2040
rp.pages.RepoAccessSettings(w, pages.RepoAccessSettingsParams{
···
2019
2047
}
2020
2048
2021
2049
func (rp *Repo) pipelineSettings(w http.ResponseWriter, r *http.Request) {
2050
+
l := rp.logger.With("handler", "pipelineSettings")
2051
+
2022
2052
f, err := rp.repoResolver.Resolve(r)
2023
2053
user := rp.oauth.GetUser(r)
2024
2054
2025
2055
// all spindles that the repo owner is a member of
2026
2056
spindles, err := rp.enforcer.GetSpindlesForUser(f.OwnerDid())
2027
2057
if err != nil {
2028
-
log.Println("failed to fetch spindles", err)
2058
+
l.Error("failed to fetch spindles", "err", err)
2029
2059
return
2030
2060
}
2031
2061
···
2038
2068
oauth.WithExp(60),
2039
2069
oauth.WithDev(rp.config.Core.Dev),
2040
2070
); err != nil {
2041
-
log.Println("failed to create spindle client", err)
2071
+
l.Error("failed to create spindle client", "err", err)
2042
2072
} else if resp, err := tangled.RepoListSecrets(r.Context(), spindleClient, f.RepoAt().String()); err != nil {
2043
-
log.Println("failed to fetch secrets", err)
2073
+
l.Error("failed to fetch secrets", "err", err)
2044
2074
} else {
2045
2075
secrets = resp.Secrets
2046
2076
}
···
2080
2110
}
2081
2111
2082
2112
func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) {
2113
+
l := rp.logger.With("handler", "SyncRepoFork")
2114
+
2083
2115
ref := chi.URLParam(r, "ref")
2084
2116
ref, _ = url.PathUnescape(ref)
2085
2117
2086
2118
user := rp.oauth.GetUser(r)
2087
2119
f, err := rp.repoResolver.Resolve(r)
2088
2120
if err != nil {
2089
-
log.Printf("failed to resolve source repo: %v", err)
2121
+
l.Error("failed to resolve source repo", "err", err)
2090
2122
return
2091
2123
}
2092
2124
···
2130
2162
}
2131
2163
2132
2164
func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) {
2165
+
l := rp.logger.With("handler", "ForkRepo")
2166
+
2133
2167
user := rp.oauth.GetUser(r)
2134
2168
f, err := rp.repoResolver.Resolve(r)
2135
2169
if err != nil {
2136
-
log.Printf("failed to resolve source repo: %v", err)
2170
+
l.Error("failed to resolve source repo", "err", err)
2137
2171
return
2138
2172
}
2139
2173
···
2184
2218
)
2185
2219
if err != nil {
2186
2220
if !errors.Is(err, sql.ErrNoRows) {
2187
-
log.Println("error fetching existing repo from db", "err", err)
2221
+
l.Error("error fetching existing repo from db", "err", err)
2188
2222
rp.pages.Notice(w, "repo", "Failed to fork this repository. Try again later.")
2189
2223
return
2190
2224
}
···
2299
2333
2300
2334
err = db.AddRepo(tx, repo)
2301
2335
if err != nil {
2302
-
log.Println(err)
2336
+
l.Error("failed to AddRepo", "err", err)
2303
2337
rp.pages.Notice(w, "repo", "Failed to save repository information.")
2304
2338
return
2305
2339
}
···
2308
2342
p, _ := securejoin.SecureJoin(user.Did, forkName)
2309
2343
err = rp.enforcer.AddRepo(user.Did, targetKnot, p)
2310
2344
if err != nil {
2311
-
log.Println(err)
2345
+
l.Error("failed to add ACLs", "err", err)
2312
2346
rp.pages.Notice(w, "repo", "Failed to set up repository permissions.")
2313
2347
return
2314
2348
}
2315
2349
2316
2350
err = tx.Commit()
2317
2351
if err != nil {
2318
-
log.Println("failed to commit changes", err)
2352
+
l.Error("failed to commit changes", "err", err)
2319
2353
http.Error(w, err.Error(), http.StatusInternalServerError)
2320
2354
return
2321
2355
}
2322
2356
2323
2357
err = rp.enforcer.E.SavePolicy()
2324
2358
if err != nil {
2325
-
log.Println("failed to update ACLs", err)
2359
+
l.Error("failed to update ACLs", "err", err)
2326
2360
http.Error(w, err.Error(), http.StatusInternalServerError)
2327
2361
return
2328
2362
}
···
2358
2392
}
2359
2393
2360
2394
func (rp *Repo) RepoCompareNew(w http.ResponseWriter, r *http.Request) {
2395
+
l := rp.logger.With("handler", "RepoCompareNew")
2396
+
2361
2397
user := rp.oauth.GetUser(r)
2362
2398
f, err := rp.repoResolver.Resolve(r)
2363
2399
if err != nil {
2364
-
log.Println("failed to get repo and knot", err)
2400
+
l.Error("failed to get repo and knot", "err", err)
2365
2401
return
2366
2402
}
2367
2403
···
2377
2413
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
2378
2414
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
2379
2415
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2380
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
2416
+
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
2381
2417
rp.pages.Error503(w)
2382
2418
return
2383
2419
}
2384
2420
2385
2421
var branchResult types.RepoBranchesResponse
2386
2422
if err := json.Unmarshal(branchBytes, &branchResult); err != nil {
2387
-
log.Println("failed to decode XRPC branches response", err)
2423
+
l.Error("failed to decode XRPC branches response", "err", err)
2388
2424
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
2389
2425
return
2390
2426
}
···
2414
2450
2415
2451
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
2416
2452
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2417
-
log.Println("failed to call XRPC repo.tags", xrpcerr)
2453
+
l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
2418
2454
rp.pages.Error503(w)
2419
2455
return
2420
2456
}
2421
2457
2422
2458
var tags types.RepoTagsResponse
2423
2459
if err := json.Unmarshal(tagBytes, &tags); err != nil {
2424
-
log.Println("failed to decode XRPC tags response", err)
2460
+
l.Error("failed to decode XRPC tags response", "err", err)
2425
2461
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
2426
2462
return
2427
2463
}
···
2439
2475
}
2440
2476
2441
2477
func (rp *Repo) RepoCompare(w http.ResponseWriter, r *http.Request) {
2478
+
l := rp.logger.With("handler", "RepoCompare")
2479
+
2442
2480
user := rp.oauth.GetUser(r)
2443
2481
f, err := rp.repoResolver.Resolve(r)
2444
2482
if err != nil {
2445
-
log.Println("failed to get repo and knot", err)
2483
+
l.Error("failed to get repo and knot", "err", err)
2446
2484
return
2447
2485
}
2448
2486
···
2469
2507
head, _ = url.PathUnescape(head)
2470
2508
2471
2509
if base == "" || head == "" {
2472
-
log.Printf("invalid comparison")
2510
+
l.Error("invalid comparison")
2473
2511
rp.pages.Error404(w)
2474
2512
return
2475
2513
}
···
2487
2525
2488
2526
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
2489
2527
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2490
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
2528
+
l.Error("failed to call XRPC repo.branches", "err", xrpcerr)
2491
2529
rp.pages.Error503(w)
2492
2530
return
2493
2531
}
2494
2532
2495
2533
var branches types.RepoBranchesResponse
2496
2534
if err := json.Unmarshal(branchBytes, &branches); err != nil {
2497
-
log.Println("failed to decode XRPC branches response", err)
2535
+
l.Error("failed to decode XRPC branches response", "err", err)
2498
2536
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
2499
2537
return
2500
2538
}
2501
2539
2502
2540
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
2503
2541
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2504
-
log.Println("failed to call XRPC repo.tags", xrpcerr)
2542
+
l.Error("failed to call XRPC repo.tags", "err", xrpcerr)
2505
2543
rp.pages.Error503(w)
2506
2544
return
2507
2545
}
2508
2546
2509
2547
var tags types.RepoTagsResponse
2510
2548
if err := json.Unmarshal(tagBytes, &tags); err != nil {
2511
-
log.Println("failed to decode XRPC tags response", err)
2549
+
l.Error("failed to decode XRPC tags response", "err", err)
2512
2550
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
2513
2551
return
2514
2552
}
2515
2553
2516
2554
compareBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, base, head)
2517
2555
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
2518
-
log.Println("failed to call XRPC repo.compare", xrpcerr)
2556
+
l.Error("failed to call XRPC repo.compare", "err", xrpcerr)
2519
2557
rp.pages.Error503(w)
2520
2558
return
2521
2559
}
2522
2560
2523
2561
var formatPatch types.RepoFormatPatchResponse
2524
2562
if err := json.Unmarshal(compareBytes, &formatPatch); err != nil {
2525
-
log.Println("failed to decode XRPC compare response", err)
2563
+
l.Error("failed to decode XRPC compare response", "err", err)
2526
2564
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
2527
2565
return
2528
2566
}
+1
-1
appview/signup/signup.go
+1
-1
appview/signup/signup.go
+3
-1
appview/state/knotstream.go
+3
-1
appview/state/knotstream.go
···
25
25
)
26
26
27
27
func Knotstream(ctx context.Context, c *config.Config, d *db.DB, enforcer *rbac.Enforcer, posthog posthog.Client) (*ec.Consumer, error) {
28
+
logger := log.FromContext(ctx)
29
+
logger = log.SubLogger(logger, "knotstream")
30
+
28
31
knots, err := db.GetRegistrations(
29
32
d,
30
33
db.FilterIsNot("registered", "null"),
···
39
42
srcs[s] = struct{}{}
40
43
}
41
44
42
-
logger := log.New("knotstream")
43
45
cache := cache.New(c.Redis.Addr)
44
46
cursorStore := cursor.NewRedisCursorStore(cache)
45
47
+7
-4
appview/state/login.go
+7
-4
appview/state/login.go
···
2
2
3
3
import (
4
4
"fmt"
5
-
"log"
6
5
"net/http"
7
6
"strings"
8
7
···
10
9
)
11
10
12
11
func (s *State) Login(w http.ResponseWriter, r *http.Request) {
12
+
l := s.logger.With("handler", "Login")
13
+
13
14
switch r.Method {
14
15
case http.MethodGet:
15
16
returnURL := r.URL.Query().Get("return_url")
···
32
33
33
34
// basic handle validation
34
35
if !strings.Contains(handle, ".") {
35
-
log.Println("invalid handle format", "raw", handle)
36
+
l.Error("invalid handle format", "raw", handle)
36
37
s.pages.Notice(
37
38
w,
38
39
"login-msg",
···
52
53
}
53
54
54
55
func (s *State) Logout(w http.ResponseWriter, r *http.Request) {
56
+
l := s.logger.With("handler", "Logout")
57
+
55
58
err := s.oauth.DeleteSession(w, r)
56
59
if err != nil {
57
-
log.Println("failed to logout", "err", err)
60
+
l.Error("failed to logout", "err", err)
58
61
} else {
59
-
log.Println("logged out successfully")
62
+
l.Info("logged out successfully")
60
63
}
61
64
62
65
s.pages.HxRedirect(w, "/login")
+59
-13
appview/state/router.go
+59
-13
appview/state/router.go
···
205
205
}
206
206
207
207
func (s *State) SpindlesRouter() http.Handler {
208
-
logger := log.New("spindles")
208
+
logger := log.SubLogger(s.logger, "spindles")
209
209
210
210
spindles := &spindles.Spindles{
211
211
Db: s.db,
···
221
221
}
222
222
223
223
func (s *State) KnotsRouter() http.Handler {
224
-
logger := log.New("knots")
224
+
logger := log.SubLogger(s.logger, "knots")
225
225
226
226
knots := &knots.Knots{
227
227
Db: s.db,
···
238
238
}
239
239
240
240
func (s *State) StringsRouter(mw *middleware.Middleware) http.Handler {
241
-
logger := log.New("strings")
241
+
logger := log.SubLogger(s.logger, "strings")
242
242
243
243
strs := &avstrings.Strings{
244
244
Db: s.db,
···
253
253
}
254
254
255
255
func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler {
256
-
issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier, s.validator)
256
+
issues := issues.New(
257
+
s.oauth,
258
+
s.repoResolver,
259
+
s.pages,
260
+
s.idResolver,
261
+
s.db,
262
+
s.config,
263
+
s.notifier,
264
+
s.validator,
265
+
log.SubLogger(s.logger, "issues"),
266
+
)
257
267
return issues.Router(mw)
258
268
}
259
269
260
270
func (s *State) PullsRouter(mw *middleware.Middleware) http.Handler {
261
-
pulls := pulls.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier, s.enforcer)
271
+
pulls := pulls.New(
272
+
s.oauth,
273
+
s.repoResolver,
274
+
s.pages,
275
+
s.idResolver,
276
+
s.db,
277
+
s.config,
278
+
s.notifier,
279
+
s.enforcer,
280
+
log.SubLogger(s.logger, "pulls"),
281
+
)
262
282
return pulls.Router(mw)
263
283
}
264
284
265
285
func (s *State) RepoRouter(mw *middleware.Middleware) http.Handler {
266
-
logger := log.New("repo")
267
-
repo := repo.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.notifier, s.enforcer, logger, s.validator)
286
+
repo := repo.New(
287
+
s.oauth,
288
+
s.repoResolver,
289
+
s.pages,
290
+
s.spindlestream,
291
+
s.idResolver,
292
+
s.db,
293
+
s.config,
294
+
s.notifier,
295
+
s.enforcer,
296
+
log.SubLogger(s.logger, "repo"),
297
+
s.validator,
298
+
)
268
299
return repo.Router(mw)
269
300
}
270
301
271
302
func (s *State) PipelinesRouter(mw *middleware.Middleware) http.Handler {
272
-
pipes := pipelines.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.enforcer)
303
+
pipes := pipelines.New(
304
+
s.oauth,
305
+
s.repoResolver,
306
+
s.pages,
307
+
s.spindlestream,
308
+
s.idResolver,
309
+
s.db,
310
+
s.config,
311
+
s.enforcer,
312
+
log.SubLogger(s.logger, "pipelines"),
313
+
)
273
314
return pipes.Router(mw)
274
315
}
275
316
276
317
func (s *State) LabelsRouter(mw *middleware.Middleware) http.Handler {
277
-
ls := labels.New(s.oauth, s.pages, s.db, s.validator, s.enforcer)
318
+
ls := labels.New(
319
+
s.oauth,
320
+
s.pages,
321
+
s.db,
322
+
s.validator,
323
+
s.enforcer,
324
+
log.SubLogger(s.logger, "labels"),
325
+
)
278
326
return ls.Router(mw)
279
327
}
280
328
281
329
func (s *State) NotificationsRouter(mw *middleware.Middleware) http.Handler {
282
-
notifs := notifications.New(s.db, s.oauth, s.pages)
330
+
notifs := notifications.New(s.db, s.oauth, s.pages, log.SubLogger(s.logger, "notifications"))
283
331
return notifs.Router(mw)
284
332
}
285
333
286
334
func (s *State) SignupRouter() http.Handler {
287
-
logger := log.New("signup")
288
-
289
-
sig := signup.New(s.config, s.db, s.posthog, s.idResolver, s.pages, logger)
335
+
sig := signup.New(s.config, s.db, s.posthog, s.idResolver, s.pages, log.SubLogger(s.logger, "signup"))
290
336
return sig.Router()
291
337
}
+3
-1
appview/state/spindlestream.go
+3
-1
appview/state/spindlestream.go
···
22
22
)
23
23
24
24
func Spindlestream(ctx context.Context, c *config.Config, d *db.DB, enforcer *rbac.Enforcer) (*ec.Consumer, error) {
25
+
logger := log.FromContext(ctx)
26
+
logger = log.SubLogger(logger, "spindlestream")
27
+
25
28
spindles, err := db.GetSpindles(
26
29
d,
27
30
db.FilterIsNot("verified", "null"),
···
36
39
srcs[src] = struct{}{}
37
40
}
38
41
39
-
logger := log.New("spindlestream")
40
42
cache := cache.New(c.Redis.Addr)
41
43
cursorStore := cursor.NewRedisCursorStore(cache)
42
44
+15
-19
appview/state/state.go
+15
-19
appview/state/state.go
···
5
5
"database/sql"
6
6
"errors"
7
7
"fmt"
8
-
"log"
9
8
"log/slog"
10
9
"net/http"
11
10
"strings"
···
13
12
14
13
"tangled.org/core/api/tangled"
15
14
"tangled.org/core/appview"
16
-
"tangled.org/core/appview/cache"
17
-
"tangled.org/core/appview/cache/session"
18
15
"tangled.org/core/appview/config"
19
16
"tangled.org/core/appview/db"
20
17
"tangled.org/core/appview/models"
···
29
26
"tangled.org/core/eventconsumer"
30
27
"tangled.org/core/idresolver"
31
28
"tangled.org/core/jetstream"
29
+
"tangled.org/core/log"
32
30
tlog "tangled.org/core/log"
33
31
"tangled.org/core/rbac"
34
32
"tangled.org/core/tid"
···
48
46
oauth *oauth.OAuth
49
47
enforcer *rbac.Enforcer
50
48
pages *pages.Pages
51
-
sess *session.SessionStore
52
49
idResolver *idresolver.Resolver
53
50
posthog posthog.Client
54
51
jc *jetstream.JetstreamClient
···
61
58
}
62
59
63
60
func Make(ctx context.Context, config *config.Config) (*State, error) {
64
-
d, err := db.Make(config.Core.DbPath)
61
+
logger := tlog.FromContext(ctx)
62
+
63
+
d, err := db.Make(ctx, config.Core.DbPath)
65
64
if err != nil {
66
65
return nil, fmt.Errorf("failed to create db: %w", err)
67
66
}
···
73
72
74
73
res, err := idresolver.RedisResolver(config.Redis.ToURL())
75
74
if err != nil {
76
-
log.Printf("failed to create redis resolver: %v", err)
75
+
logger.Error("failed to create redis resolver", "err", err)
77
76
res = idresolver.DefaultResolver()
78
77
}
79
78
···
82
81
return nil, fmt.Errorf("failed to create posthog client: %w", err)
83
82
}
84
83
85
-
pages := pages.NewPages(config, res)
86
-
cache := cache.New(config.Redis.Addr)
87
-
sess := session.New(cache)
88
-
oauth2, err := oauth.New(config, posthog, d, enforcer, res)
84
+
pages := pages.NewPages(config, res, log.SubLogger(logger, "pages"))
85
+
oauth, err := oauth.New(config, posthog, d, enforcer, res)
89
86
if err != nil {
90
87
return nil, fmt.Errorf("failed to start oauth handler: %w", err)
91
88
}
···
112
109
tangled.LabelOpNSID,
113
110
},
114
111
nil,
115
-
slog.Default(),
112
+
tlog.SubLogger(logger, "jetstream"),
116
113
wrapper,
117
114
false,
118
115
···
133
130
Enforcer: enforcer,
134
131
IdResolver: res,
135
132
Config: config,
136
-
Logger: tlog.New("ingester"),
133
+
Logger: log.SubLogger(logger, "ingester"),
137
134
Validator: validator,
138
135
}
139
136
err = jc.StartJetstream(ctx, ingester.Ingest())
···
167
164
state := &State{
168
165
d,
169
166
notifier,
170
-
oauth2,
167
+
oauth,
171
168
enforcer,
172
169
pages,
173
-
sess,
174
170
res,
175
171
posthog,
176
172
jc,
···
178
174
repoResolver,
179
175
knotstream,
180
176
spindlestream,
181
-
slog.Default(),
177
+
logger,
182
178
validator,
183
179
}
184
180
···
277
273
}
278
274
timeline, err := db.MakeTimeline(s.db, 50, userDid, filtered)
279
275
if err != nil {
280
-
log.Println(err)
276
+
s.logger.Error("failed to make timeline", "err", err)
281
277
s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.")
282
278
}
283
279
284
280
repos, err := db.GetTopStarredReposLastWeek(s.db)
285
281
if err != nil {
286
-
log.Println(err)
282
+
s.logger.Error("failed to get top starred repos", "err", err)
287
283
s.pages.Notice(w, "topstarredrepos", "Unable to load.")
288
284
return
289
285
}
···
344
340
345
341
timeline, err := db.MakeTimeline(s.db, 5, "", filtered)
346
342
if err != nil {
347
-
log.Println(err)
343
+
s.logger.Error("failed to make timeline", "err", err)
348
344
s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.")
349
345
return
350
346
}
351
347
352
348
repos, err := db.GetTopStarredReposLastWeek(s.db)
353
349
if err != nil {
354
-
log.Println(err)
350
+
s.logger.Error("failed to get top starred repos", "err", err)
355
351
s.pages.Notice(w, "topstarredrepos", "Unable to load.")
356
352
return
357
353
}
+14
-9
cmd/appview/main.go
+14
-9
cmd/appview/main.go
···
2
2
3
3
import (
4
4
"context"
5
-
"log"
6
-
"log/slog"
7
5
"net/http"
8
6
"os"
9
7
10
8
"tangled.org/core/appview/config"
11
9
"tangled.org/core/appview/state"
10
+
tlog "tangled.org/core/log"
12
11
)
13
12
14
13
func main() {
15
-
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, nil)))
16
-
17
14
ctx := context.Background()
15
+
logger := tlog.New("appview")
16
+
ctx = tlog.IntoContext(ctx, logger)
18
17
19
18
c, err := config.LoadConfig(ctx)
20
19
if err != nil {
21
-
log.Println("failed to load config", "error", err)
20
+
logger.Error("failed to load config", "error", err)
22
21
return
23
22
}
24
23
25
24
state, err := state.Make(ctx, c)
26
25
defer func() {
27
-
log.Println(state.Close())
26
+
if err := state.Close(); err != nil {
27
+
logger.Error("failed to close state", "err", err)
28
+
}
28
29
}()
29
30
30
31
if err != nil {
31
-
log.Fatal(err)
32
+
logger.Error("failed to start appview", "err", err)
33
+
os.Exit(-1)
32
34
}
33
35
34
-
log.Println("starting server on", c.Core.ListenAddr)
35
-
log.Println(http.ListenAndServe(c.Core.ListenAddr, state.Router()))
36
+
logger.Info("starting server", "address", c.Core.ListenAddr)
37
+
38
+
if err := http.ListenAndServe(c.Core.ListenAddr, state.Router()); err != nil {
39
+
logger.Error("failed to start appview", "err", err)
40
+
}
36
41
}
+9
-3
cmd/spindle/main.go
+9
-3
cmd/spindle/main.go
···
2
2
3
3
import (
4
4
"context"
5
+
"log/slog"
5
6
"os"
6
7
7
-
"tangled.org/core/log"
8
+
tlog "tangled.org/core/log"
8
9
"tangled.org/core/spindle"
9
10
_ "tangled.org/core/tid"
10
11
)
11
12
12
13
func main() {
13
-
ctx := log.NewContext(context.Background(), "spindle")
14
+
logger := tlog.New("spindl3")
15
+
slog.SetDefault(logger)
16
+
17
+
ctx := context.Background()
18
+
ctx = tlog.IntoContext(ctx, logger)
19
+
14
20
err := spindle.Run(ctx)
15
21
if err != nil {
16
-
log.FromContext(ctx).Error("error running spindle", "error", err)
22
+
logger.Error("error running spindle", "error", err)
17
23
os.Exit(-1)
18
24
}
19
25
}
+13
go.mod
+13
go.mod
···
60
60
github.com/ProtonMail/go-crypto v1.3.0 // indirect
61
61
github.com/alecthomas/repr v0.4.0 // indirect
62
62
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
63
+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
63
64
github.com/aymerick/douceur v0.2.0 // indirect
64
65
github.com/beorn7/perks v1.0.1 // indirect
65
66
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
66
67
github.com/casbin/govaluate v1.3.0 // indirect
67
68
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
68
69
github.com/cespare/xxhash/v2 v2.3.0 // indirect
70
+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
71
+
github.com/charmbracelet/lipgloss v1.1.0 // indirect
72
+
github.com/charmbracelet/log v0.4.2 // indirect
73
+
github.com/charmbracelet/x/ansi v0.8.0 // indirect
74
+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
75
+
github.com/charmbracelet/x/term v0.2.1 // indirect
69
76
github.com/cloudflare/circl v1.6.2-0.20250618153321-aa837fd1539d // indirect
70
77
github.com/containerd/errdefs v1.0.0 // indirect
71
78
github.com/containerd/errdefs/pkg v0.3.0 // indirect
···
84
91
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
85
92
github.com/go-git/go-billy/v5 v5.6.2 // indirect
86
93
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
94
+
github.com/go-logfmt/logfmt v0.6.0 // indirect
87
95
github.com/go-logr/logr v1.4.3 // indirect
88
96
github.com/go-logr/stdr v1.2.2 // indirect
89
97
github.com/go-redis/cache/v9 v9.0.0 // indirect
···
126
134
github.com/lestrrat-go/httprc v1.0.6 // indirect
127
135
github.com/lestrrat-go/iter v1.0.2 // indirect
128
136
github.com/lestrrat-go/option v1.0.1 // indirect
137
+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
129
138
github.com/mattn/go-isatty v0.0.20 // indirect
139
+
github.com/mattn/go-runewidth v0.0.16 // indirect
130
140
github.com/minio/sha256-simd v1.0.1 // indirect
131
141
github.com/mitchellh/mapstructure v1.5.0 // indirect
132
142
github.com/moby/docker-image-spec v1.3.1 // indirect
···
134
144
github.com/moby/term v0.5.2 // indirect
135
145
github.com/morikuni/aec v1.0.0 // indirect
136
146
github.com/mr-tron/base58 v1.2.0 // indirect
147
+
github.com/muesli/termenv v0.16.0 // indirect
137
148
github.com/multiformats/go-base32 v0.1.0 // indirect
138
149
github.com/multiformats/go-base36 v0.2.0 // indirect
139
150
github.com/multiformats/go-multibase v0.2.0 // indirect
···
152
163
github.com/prometheus/client_model v0.6.2 // indirect
153
164
github.com/prometheus/common v0.64.0 // indirect
154
165
github.com/prometheus/procfs v0.16.1 // indirect
166
+
github.com/rivo/uniseg v0.4.7 // indirect
155
167
github.com/ryanuber/go-glob v1.0.0 // indirect
156
168
github.com/segmentio/asm v1.2.0 // indirect
157
169
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
···
160
172
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
161
173
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
162
174
github.com/wyatt915/treeblood v0.1.15 // indirect
175
+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
163
176
gitlab.com/staticnoise/goldmark-callout v0.0.0-20240609120641-6366b799e4ab // indirect
164
177
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
165
178
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
+27
go.sum
+27
go.sum
···
19
19
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
20
20
github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk=
21
21
github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA=
22
+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
23
+
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
22
24
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
23
25
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
24
26
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
···
48
50
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
49
51
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
50
52
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
53
+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
54
+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
55
+
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
56
+
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
57
+
github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
58
+
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
59
+
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
60
+
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
61
+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
62
+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
63
+
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
64
+
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
51
65
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
52
66
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
53
67
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
···
120
134
github.com/go-git/go-git-fixtures/v5 v5.0.0-20241203230421-0753e18f8f03/go.mod h1:hMKrMnUE4W0SJ7bFyM00dyz/HoknZoptGWzrj6M+dEM=
121
135
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
122
136
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
137
+
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
138
+
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
123
139
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
124
140
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
125
141
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
···
276
292
github.com/lestrrat-go/jwx/v2 v2.1.6/go.mod h1:Y722kU5r/8mV7fYDifjug0r8FK8mZdw0K0GpJw/l8pU=
277
293
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
278
294
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
295
+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
296
+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
279
297
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
280
298
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
281
299
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
282
300
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
301
+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
302
+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
283
303
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
284
304
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
285
305
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
···
300
320
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
301
321
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
302
322
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
323
+
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
324
+
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
303
325
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
304
326
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
305
327
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
···
377
399
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
378
400
github.com/resend/resend-go/v2 v2.15.0 h1:B6oMEPf8IEQwn2Ovx/9yymkESLDSeNfLFaNMw+mzHhE=
379
401
github.com/resend/resend-go/v2 v2.15.0/go.mod h1:3YCb8c8+pLiqhtRFXTyFwlLvfjQtluxOr9HEh2BwCkQ=
402
+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
403
+
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
404
+
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
380
405
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
381
406
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
382
407
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
···
434
459
github.com/wyatt915/goldmark-treeblood v0.0.0-20250825231212-5dcbdb2f4b57/go.mod h1:BxSCWByWSRSuembL3cDG1IBUbkBoO/oW/6tF19aA4hs=
435
460
github.com/wyatt915/treeblood v0.1.15 h1:3KZ3o2LpcKZAzOLqMoW9qeUzKEaKArKpbcPpTkNfQC8=
436
461
github.com/wyatt915/treeblood v0.1.15/go.mod h1:i7+yhhmzdDP17/97pIsOSffw74EK/xk+qJ0029cSXUY=
462
+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
463
+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
437
464
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
438
465
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
439
466
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+1
-1
jetstream/jetstream.go
+1
-1
jetstream/jetstream.go
···
114
114
115
115
sched := sequential.NewScheduler(j.ident, logger, j.withDidFilter(processFunc))
116
116
117
-
client, err := client.NewClient(j.cfg, log.New("jetstream"), sched)
117
+
client, err := client.NewClient(j.cfg, logger, sched)
118
118
if err != nil {
119
119
return fmt.Errorf("failed to create jetstream client: %w", err)
120
120
}
+39
nix/gomod2nix.toml
+39
nix/gomod2nix.toml
···
29
29
[mod."github.com/avast/retry-go/v4"]
30
30
version = "v4.6.1"
31
31
hash = "sha256-PeZc8k4rDV64+k8nZt/oy1YNVbLevltXP3ZD1jf6Z6k="
32
+
[mod."github.com/aymanbagabas/go-osc52/v2"]
33
+
version = "v2.0.1"
34
+
hash = "sha256-6Bp0jBZ6npvsYcKZGHHIUSVSTAMEyieweAX2YAKDjjg="
32
35
[mod."github.com/aymerick/douceur"]
33
36
version = "v0.2.0"
34
37
hash = "sha256-NiBX8EfOvLXNiK3pJaZX4N73YgfzdrzRXdiBFe3X3sE="
···
63
66
[mod."github.com/cespare/xxhash/v2"]
64
67
version = "v2.3.0"
65
68
hash = "sha256-7hRlwSR+fos1kx4VZmJ/7snR7zHh8ZFKX+qqqqGcQpY="
69
+
[mod."github.com/charmbracelet/colorprofile"]
70
+
version = "v0.2.3-0.20250311203215-f60798e515dc"
71
+
hash = "sha256-D9E/bMOyLXAUVOHA1/6o3i+vVmLfwIMOWib6sU7A6+Q="
72
+
[mod."github.com/charmbracelet/lipgloss"]
73
+
version = "v1.1.0"
74
+
hash = "sha256-RHsRT2EZ1nDOElxAK+6/DC9XAaGVjDTgPvRh3pyCfY4="
75
+
[mod."github.com/charmbracelet/log"]
76
+
version = "v0.4.2"
77
+
hash = "sha256-3w1PCM/c4JvVEh2d0sMfv4C77Xs1bPa1Ea84zdynC7I="
78
+
[mod."github.com/charmbracelet/x/ansi"]
79
+
version = "v0.8.0"
80
+
hash = "sha256-/YyDkGrULV2BtnNk3ojeSl0nUWQwIfIdW7WJuGbAZas="
81
+
[mod."github.com/charmbracelet/x/cellbuf"]
82
+
version = "v0.0.13-0.20250311204145-2c3ea96c31dd"
83
+
hash = "sha256-XAhCOt8qJ2vR77lH1ez0IVU1/2CaLTq9jSmrHVg5HHU="
84
+
[mod."github.com/charmbracelet/x/term"]
85
+
version = "v0.2.1"
86
+
hash = "sha256-VBkCZLI90PhMasftGw3403IqoV7d3E5WEGAIVrN5xQM="
66
87
[mod."github.com/cloudflare/circl"]
67
88
version = "v1.6.2-0.20250618153321-aa837fd1539d"
68
89
hash = "sha256-0s/i/XmMcuvPQ+qK9OIU5KxwYZyLVXRtdlYvIXRJT3Y="
···
145
166
[mod."github.com/go-jose/go-jose/v3"]
146
167
version = "v3.0.4"
147
168
hash = "sha256-RrLHCu9l6k0XVobdZQJ9Sx/VTQcWjrdLR5BEG7yXTEQ="
169
+
[mod."github.com/go-logfmt/logfmt"]
170
+
version = "v0.6.0"
171
+
hash = "sha256-RtIG2qARd5sT10WQ7F3LR8YJhS8exs+KiuUiVf75bWg="
148
172
[mod."github.com/go-logr/logr"]
149
173
version = "v1.4.3"
150
174
hash = "sha256-Nnp/dEVNMxLp3RSPDHZzGbI8BkSNuZMX0I0cjWKXXLA="
···
298
322
[mod."github.com/lestrrat-go/option"]
299
323
version = "v1.0.1"
300
324
hash = "sha256-jVcIYYVsxElIS/l2akEw32vdEPR8+anR6oeT1FoYULI="
325
+
[mod."github.com/lucasb-eyer/go-colorful"]
326
+
version = "v1.2.0"
327
+
hash = "sha256-Gg9dDJFCTaHrKHRR1SrJgZ8fWieJkybljybkI9x0gyE="
301
328
[mod."github.com/mattn/go-isatty"]
302
329
version = "v0.0.20"
303
330
hash = "sha256-qhw9hWtU5wnyFyuMbKx+7RB8ckQaFQ8D+8GKPkN3HHQ="
331
+
[mod."github.com/mattn/go-runewidth"]
332
+
version = "v0.0.16"
333
+
hash = "sha256-NC+ntvwIpqDNmXb7aixcg09il80ygq6JAnW0Gb5b/DQ="
304
334
[mod."github.com/mattn/go-sqlite3"]
305
335
version = "v1.14.24"
306
336
hash = "sha256-taGKFZFQlR5++5b2oZ1dYS3RERKv6yh1gniNWhb4egg="
···
328
358
[mod."github.com/mr-tron/base58"]
329
359
version = "v1.2.0"
330
360
hash = "sha256-8FzMu3kHUbBX10pUdtGf59Ag7BNupx8ZHeUaodR1/Vk="
361
+
[mod."github.com/muesli/termenv"]
362
+
version = "v0.16.0"
363
+
hash = "sha256-hGo275DJlyLtcifSLpWnk8jardOksdeX9lH4lBeE3gI="
331
364
[mod."github.com/multiformats/go-base32"]
332
365
version = "v0.1.0"
333
366
hash = "sha256-O2IM7FB+Y9MkDdZztyQL5F8oEnmON2Yew7XkotQziio="
···
394
427
[mod."github.com/resend/resend-go/v2"]
395
428
version = "v2.15.0"
396
429
hash = "sha256-1lMoxuMLQXaNWFKadS6rpztAKwvIl3/LWMXqw7f5WYg="
430
+
[mod."github.com/rivo/uniseg"]
431
+
version = "v0.4.7"
432
+
hash = "sha256-rDcdNYH6ZD8KouyyiZCUEy8JrjOQoAkxHBhugrfHjFo="
397
433
[mod."github.com/ryanuber/go-glob"]
398
434
version = "v1.0.0"
399
435
hash = "sha256-YkMl1utwUhi3E0sHK23ISpAsPyj4+KeXyXKoFYGXGVY="
···
440
476
[mod."github.com/wyatt915/treeblood"]
441
477
version = "v0.1.15"
442
478
hash = "sha256-hb99exdkoY2Qv8WdDxhwgPXGbEYimUr6wFtPXEvcO9g="
479
+
[mod."github.com/xo/terminfo"]
480
+
version = "v0.0.0-20220910002029-abceb7e1c41e"
481
+
hash = "sha256-GyCDxxMQhXA3Pi/TsWXpA8cX5akEoZV7CFx4RO3rARU="
443
482
[mod."github.com/yuin/goldmark"]
444
483
version = "v1.7.13"
445
484
hash = "sha256-vBCxZrPYPc8x/nvAAv3Au59dCCyfS80Vw3/a9EXK7TE="
+5
-4
xrpc/serviceauth/service_auth.go
+5
-4
xrpc/serviceauth/service_auth.go
···
9
9
10
10
"github.com/bluesky-social/indigo/atproto/auth"
11
11
"tangled.org/core/idresolver"
12
+
"tangled.org/core/log"
12
13
xrpcerr "tangled.org/core/xrpc/errors"
13
14
)
14
15
···
22
23
23
24
func NewServiceAuth(logger *slog.Logger, resolver *idresolver.Resolver, audienceDid string) *ServiceAuth {
24
25
return &ServiceAuth{
25
-
logger: logger,
26
+
logger: log.SubLogger(logger, "serviceauth"),
26
27
resolver: resolver,
27
28
audienceDid: audienceDid,
28
29
}
···
30
31
31
32
func (sa *ServiceAuth) VerifyServiceAuth(next http.Handler) http.Handler {
32
33
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
33
-
l := sa.logger.With("url", r.URL)
34
-
35
34
token := r.Header.Get("Authorization")
36
35
token = strings.TrimPrefix(token, "Bearer ")
37
36
···
42
41
43
42
did, err := s.Validate(r.Context(), token, nil)
44
43
if err != nil {
45
-
l.Error("signature verification failed", "err", err)
44
+
sa.logger.Error("signature verification failed", "err", err)
46
45
writeError(w, xrpcerr.AuthError(err), http.StatusForbidden)
47
46
return
48
47
}
48
+
49
+
sa.logger.Debug("valid signature", ActorDid, did)
49
50
50
51
r = r.WithContext(
51
52
context.WithValue(r.Context(), ActorDid, did),