An atproto PDS written in Go
at main 2.4 kB view raw
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}