An atproto PDS written in Go
at v0.5.1 2.3 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 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}