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