1package server
2
3import (
4 "strings"
5
6 "github.com/Azure/go-autorest/autorest/to"
7 "github.com/haileyok/cocoon/identity"
8 "github.com/haileyok/cocoon/internal/helpers"
9 "github.com/haileyok/cocoon/models"
10 "github.com/labstack/echo/v4"
11 "gorm.io/gorm"
12)
13
14type ComAtprotoRepoDescribeRepoResponse struct {
15 Did string `json:"did"`
16 Handle string `json:"handle"`
17 DidDoc identity.DidDoc `json:"didDoc"`
18 Collections []string `json:"collections"`
19 HandleIsCorrect bool `json:"handleIsCorrect"`
20}
21
22func (s *Server) handleDescribeRepo(e echo.Context) error {
23 ctx := e.Request().Context()
24
25 did := e.QueryParam("repo")
26 repo, err := s.getRepoActorByDid(ctx, did)
27 if err != nil {
28 if err == gorm.ErrRecordNotFound {
29 return helpers.InputError(e, to.StringPtr("RepoNotFound"))
30 }
31
32 s.logger.Error("error looking up repo", "error", err)
33 return helpers.ServerError(e, nil)
34 }
35
36 handleIsCorrect := true
37
38 diddoc, err := s.passport.FetchDoc(e.Request().Context(), repo.Repo.Did)
39 if err != nil {
40 s.logger.Error("error fetching diddoc", "error", err)
41 return helpers.ServerError(e, nil)
42 }
43
44 dochandle := ""
45 for _, aka := range diddoc.AlsoKnownAs {
46 if strings.HasPrefix(aka, "at://") {
47 dochandle = strings.TrimPrefix(aka, "at://")
48 break
49 }
50 }
51
52 if repo.Handle != dochandle {
53 handleIsCorrect = false
54 }
55
56 if handleIsCorrect {
57 resolvedDid, err := s.passport.ResolveHandle(e.Request().Context(), repo.Handle)
58 if err != nil {
59 e.Logger().Error("error resolving handle", "error", err)
60 return helpers.ServerError(e, nil)
61 }
62
63 if resolvedDid != repo.Repo.Did {
64 handleIsCorrect = false
65 }
66 }
67
68 var records []models.Record
69 if err := s.db.Raw(ctx, "SELECT DISTINCT(nsid) FROM records WHERE did = ?", nil, repo.Repo.Did).Scan(&records).Error; err != nil {
70 s.logger.Error("error getting collections", "error", err)
71 return helpers.ServerError(e, nil)
72 }
73
74 var collections []string = make([]string, 0, len(records))
75 for _, r := range records {
76 collections = append(collections, r.Nsid)
77 }
78
79 return e.JSON(200, ComAtprotoRepoDescribeRepoResponse{
80 Did: repo.Repo.Did,
81 Handle: repo.Handle,
82 DidDoc: *diddoc,
83 Collections: collections,
84 HandleIsCorrect: handleIsCorrect,
85 })
86}