forked from hailey.at/cocoon
An atproto PDS written in Go
at main 2.9 kB view raw
1package server 2 3import ( 4 "context" 5 "time" 6 7 "github.com/bluesky-social/indigo/atproto/atcrypto" 8 "github.com/haileyok/cocoon/internal/helpers" 9 "github.com/haileyok/cocoon/models" 10 "github.com/labstack/echo/v4" 11) 12 13type ServerReserveSigningKeyRequest struct { 14 Did *string `json:"did"` 15} 16 17type ServerReserveSigningKeyResponse struct { 18 SigningKey string `json:"signingKey"` 19} 20 21func (s *Server) handleServerReserveSigningKey(e echo.Context) error { 22 ctx := e.Request().Context() 23 logger := s.logger.With("name", "handleServerReserveSigningKey") 24 25 var req ServerReserveSigningKeyRequest 26 if err := e.Bind(&req); err != nil { 27 logger.Error("could not bind reserve signing key request", "error", err) 28 return helpers.ServerError(e, nil) 29 } 30 31 if req.Did != nil && *req.Did != "" { 32 var existing models.ReservedKey 33 if err := s.db.Raw(ctx, "SELECT * FROM reserved_keys WHERE did = ?", nil, *req.Did).Scan(&existing).Error; err == nil && existing.KeyDid != "" { 34 return e.JSON(200, ServerReserveSigningKeyResponse{ 35 SigningKey: existing.KeyDid, 36 }) 37 } 38 } 39 40 k, err := atcrypto.GeneratePrivateKeyK256() 41 if err != nil { 42 logger.Error("error creating signing key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err) 43 return helpers.ServerError(e, nil) 44 } 45 46 pubKey, err := k.PublicKey() 47 if err != nil { 48 logger.Error("error getting public key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err) 49 return helpers.ServerError(e, nil) 50 } 51 52 keyDid := pubKey.DIDKey() 53 54 reservedKey := models.ReservedKey{ 55 KeyDid: keyDid, 56 Did: req.Did, 57 PrivateKey: k.Bytes(), 58 CreatedAt: time.Now(), 59 } 60 61 if err := s.db.Create(ctx, &reservedKey, nil).Error; err != nil { 62 logger.Error("error storing reserved key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err) 63 return helpers.ServerError(e, nil) 64 } 65 66 logger.Info("reserved signing key", "keyDid", keyDid, "forDid", req.Did) 67 68 return e.JSON(200, ServerReserveSigningKeyResponse{ 69 SigningKey: keyDid, 70 }) 71} 72 73func (s *Server) getReservedKey(ctx context.Context, keyDidOrDid string) (*models.ReservedKey, error) { 74 var reservedKey models.ReservedKey 75 76 if err := s.db.Raw(ctx, "SELECT * FROM reserved_keys WHERE key_did = ?", nil, keyDidOrDid).Scan(&reservedKey).Error; err == nil && reservedKey.KeyDid != "" { 77 return &reservedKey, nil 78 } 79 80 if err := s.db.Raw(ctx, "SELECT * FROM reserved_keys WHERE did = ?", nil, keyDidOrDid).Scan(&reservedKey).Error; err == nil && reservedKey.KeyDid != "" { 81 return &reservedKey, nil 82 } 83 84 return nil, nil 85} 86 87func (s *Server) deleteReservedKey(ctx context.Context, keyDid string, did *string) error { 88 if err := s.db.Exec(ctx, "DELETE FROM reserved_keys WHERE key_did = ?", nil, keyDid).Error; err != nil { 89 return err 90 } 91 92 if did != nil && *did != "" { 93 if err := s.db.Exec(ctx, "DELETE FROM reserved_keys WHERE did = ?", nil, *did).Error; err != nil { 94 return err 95 } 96 } 97 98 return nil 99}