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 logger := s.logger.With("name", "handleDescribeRepo")
25
26 did := e.QueryParam("repo")
27 repo, err := s.getRepoActorByDid(ctx, did)
28 if err != nil {
29 if err == gorm.ErrRecordNotFound {
30 return helpers.InputError(e, to.StringPtr("RepoNotFound"))
31 }
32
33 logger.Error("error looking up repo", "error", err)
34 return helpers.ServerError(e, nil)
35 }
36
37 handleIsCorrect := true
38
39 diddoc, err := s.passport.FetchDoc(e.Request().Context(), repo.Repo.Did)
40 if err != nil {
41 logger.Error("error fetching diddoc", "error", err)
42 return helpers.ServerError(e, nil)
43 }
44
45 dochandle := ""
46 for _, aka := range diddoc.AlsoKnownAs {
47 if strings.HasPrefix(aka, "at://") {
48 dochandle = strings.TrimPrefix(aka, "at://")
49 break
50 }
51 }
52
53 if repo.Handle != dochandle {
54 handleIsCorrect = false
55 }
56
57 if handleIsCorrect {
58 resolvedDid, err := s.passport.ResolveHandle(e.Request().Context(), repo.Handle)
59 if err != nil {
60 e.Logger().Error("error resolving handle", "error", err)
61 return helpers.ServerError(e, nil)
62 }
63
64 if resolvedDid != repo.Repo.Did {
65 handleIsCorrect = false
66 }
67 }
68
69 var records []models.Record
70 if err := s.db.Raw(ctx, "SELECT DISTINCT(nsid) FROM records WHERE did = ?", nil, repo.Repo.Did).Scan(&records).Error; err != nil {
71 logger.Error("error getting collections", "error", err)
72 return helpers.ServerError(e, nil)
73 }
74
75 var collections []string = make([]string, 0, len(records))
76 for _, r := range records {
77 collections = append(collections, r.Nsid)
78 }
79
80 return e.JSON(200, ComAtprotoRepoDescribeRepoResponse{
81 Did: repo.Repo.Did,
82 Handle: repo.Handle,
83 DidDoc: *diddoc,
84 Collections: collections,
85 HandleIsCorrect: handleIsCorrect,
86 })
87}