Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "feat : sp endpoints for v2" #831

Merged
merged 1 commit into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 53 additions & 50 deletions api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,61 +100,64 @@ func (s *apiV1) RegisterRoutes(e *echo.Echo) {
e.POST("/register", s.handleRegisterUser)
e.POST("/login", s.handleLoginUser)
e.GET("/health", s.handleHealth)
e.GET("/viewer", util.WithUser(s.handleGetViewer), s.AuthRequired(util.PermLevelUpload))
e.GET("/viewer", withUser(s.handleGetViewer), s.AuthRequired(util.PermLevelUpload))
e.GET("/retrieval-candidates/:cid", s.handleGetRetrievalCandidates)
e.GET("/gw/:path", s.handleGateway)

e.POST("/put", util.WithMultipartFormDataChecker(util.WithUser(s.handleAdd)), s.AuthRequired(util.PermLevelUpload))
e.POST("/put", util.WithMultipartFormDataChecker(withUser(s.handleAdd)), s.AuthRequired(util.PermLevelUpload))
e.GET("/get/:cid", s.handleGetFullContentbyCid)
// e.HEAD("/get/:cid", s.handleGetContentByCid)

user := e.Group("/user")
user.Use(s.AuthRequired(util.PermLevelUser))
user.GET("/api-keys", util.WithUser(s.handleUserGetApiKeys))
user.POST("/api-keys", util.WithUser(s.handleUserCreateApiKey))
user.DELETE("/api-keys/:key_or_hash", util.WithUser(s.handleUserRevokeApiKey))
user.GET("/export", util.WithUser(s.handleUserExportData))
user.PUT("/password", util.WithUser(s.handleUserChangePassword))
user.PUT("/address", util.WithUser(s.handleUserChangeAddress))
user.GET("/stats", util.WithUser(s.handleGetUserStats))
user.GET("/api-keys", withUser(s.handleUserGetApiKeys))
user.POST("/api-keys", withUser(s.handleUserCreateApiKey))
user.DELETE("/api-keys/:key_or_hash", withUser(s.handleUserRevokeApiKey))
user.GET("/export", withUser(s.handleUserExportData))
user.PUT("/password", withUser(s.handleUserChangePassword))
user.PUT("/address", withUser(s.handleUserChangeAddress))
user.GET("/stats", withUser(s.handleGetUserStats))

userMiner := user.Group("/miner")
userMiner.POST("/claim", util.WithUser(s.handleUserClaimMiner))
userMiner.GET("/claim/:miner", util.WithUser(s.handleUserGetClaimMinerMsg))
userMiner.POST("/suspend/:miner", util.WithUser(s.handleSuspendMiner))
userMiner.PUT("/unsuspend/:miner", util.WithUser(s.handleUnsuspendMiner))
userMiner.PUT("/set-info/:miner", util.WithUser(s.handleMinersSetInfo))
userMiner.POST("/claim", withUser(s.handleUserClaimMiner))
userMiner.GET("/claim/:miner", withUser(s.handleUserGetClaimMinerMsg))
userMiner.POST("/suspend/:miner", withUser(s.handleSuspendMiner))
userMiner.PUT("/unsuspend/:miner", withUser(s.handleUnsuspendMiner))
userMiner.PUT("/set-info/:miner", withUser(s.handleMinersSetInfo))

contmeta := e.Group("/content")
uploads := contmeta.Group("", s.AuthRequired(util.PermLevelUpload))
uploads.POST("/add", util.WithMultipartFormDataChecker(util.WithUser(s.handleAdd)))
uploads.POST("/add-ipfs", util.WithUser(s.handleAddIpfs))
uploads.POST("/add-car", util.WithContentLengthCheck(util.WithUser(s.handleAddCar)))
uploads.POST("/create", util.WithUser(s.handleCreateContent))
uploads.POST("/add", util.WithMultipartFormDataChecker(withUser(s.handleAdd)))
uploads.POST("/add-ipfs", withUser(s.handleAddIpfs))
uploads.POST("/add-car", util.WithContentLengthCheck(withUser(s.handleAddCar)))
uploads.POST("/create", withUser(s.handleCreateContent))

content := contmeta.Group("", s.AuthRequired(util.PermLevelUser))
content.GET("/by-cid/:cid", s.handleGetContentByCid)
content.GET("/:cont_id", util.WithUser(s.handleGetContent))
content.GET("/stats", util.WithUser(s.handleStats))
content.GET("/:cont_id", withUser(s.handleGetContent))
content.GET("/stats", withUser(s.handleStats))
content.GET("/contents", withUser(s.handleGetUserContents))
content.GET("/ensure-replication/:datacid", s.handleEnsureReplication)
content.GET("/status/:id", util.WithUser(s.handleContentStatus))
content.GET("/list", util.WithUser(s.handleListContent))
content.GET("/deals", util.WithUser(s.handleListContentWithDeals))
content.GET("/failures/:content", util.WithUser(s.handleGetContentFailures))
content.GET("/bw-usage/:content", util.WithUser(s.handleGetContentBandwidth))
content.GET("/staging-zones", util.WithUser(s.handleGetStagingZoneForUser))
content.GET("/aggregated/:content", util.WithUser(s.handleGetAggregatedForContent))
content.GET("/all-deals", util.WithUser(s.handleGetAllDealsForUser))
content.GET("/status/:id", withUser(s.handleContentStatus))
content.GET("/list", withUser(s.handleListContent))
content.GET("/deals", withUser(s.handleListContentWithDeals))
content.GET("/failures/:content", withUser(s.handleGetContentFailures))
content.GET("/bw-usage/:content", withUser(s.handleGetContentBandwidth))
content.GET("/staging-zones", withUser(s.handleGetStagingZonesForUser))
content.GET("/staging-zones/:staging_zone", withUser(s.handleGetStagingZoneWithoutContents))
content.GET("/staging-zones/:staging_zone/contents", withUser(s.handleGetStagingZoneContents))
content.GET("/aggregated/:content", withUser(s.handleGetAggregatedForContent))
content.GET("/all-deals", withUser(s.handleGetAllDealsForUser))

// TODO: the commented out routes here are still fairly useful, but maybe
// need to have some sort of 'super user' permission level in order to use
// them? Can easily cause harm using them
deals := e.Group("/deals")
deals.Use(s.AuthRequired(util.PermLevelUser))
deals.GET("/status/:deal", util.WithUser(s.handleGetDealStatus))
deals.GET("/status-by-proposal/:propcid", util.WithUser(s.handleGetDealStatusByPropCid))
deals.GET("/status/:deal", withUser(s.handleGetDealStatus))
deals.GET("/status-by-proposal/:propcid", withUser(s.handleGetDealStatusByPropCid))
deals.GET("/query/:miner", s.handleQueryAsk)
deals.POST("/make/:miner", util.WithUser(s.handleMakeDeal))
deals.POST("/make/:miner", withUser(s.handleMakeDeal))
//deals.POST("/transfer/start/:miner/:propcid/:datacid", s.handleTransferStart)
deals.GET("/transfer/status/:id", s.handleTransferStatusByID)
deals.POST("/transfer/status", s.handleTransferStatus)
Expand All @@ -163,29 +166,29 @@ func (s *apiV1) RegisterRoutes(e *echo.Echo) {
deals.POST("/estimate", s.handleEstimateDealCost)
deals.GET("/proposal/:propcid", s.handleGetProposal)
deals.GET("/info/:dealid", s.handleGetDealInfo)
deals.GET("/failures", util.WithUser(s.handleStorageFailures))
deals.GET("/failures", withUser(s.handleStorageFailures))

cols := e.Group("/collections")
cols.Use(s.AuthRequired(util.PermLevelUser))
cols.GET("", util.WithUser(s.handleListCollections))
cols.POST("", util.WithUser(s.handleCreateCollection))
cols.DELETE("/:coluuid", util.WithUser(s.handleDeleteCollection))
cols.POST("/:coluuid", util.WithUser(s.handleAddContentsToCollection))
cols.GET("/:coluuid", util.WithUser(s.handleGetCollectionContents))
cols.DELETE("/:coluuid/contents", util.WithUser(s.handleDeleteContentFromCollection))
cols.POST("/:coluuid/commit", util.WithUser(s.handleCommitCollection))
cols.GET("", withUser(s.handleListCollections))
cols.POST("", withUser(s.handleCreateCollection))
cols.DELETE("/:coluuid", withUser(s.handleDeleteCollection))
cols.POST("/:coluuid", withUser(s.handleAddContentsToCollection))
cols.GET("/:coluuid", withUser(s.handleGetCollectionContents))
cols.DELETE("/:coluuid/contents", withUser(s.handleDeleteContentFromCollection))
cols.POST("/:coluuid/commit", withUser(s.handleCommitCollection))
colfs := cols.Group("/fs")
colfs.POST("/add", util.WithUser(s.handleColfsAdd))
colfs.POST("/add", withUser(s.handleColfsAdd))

pinning := e.Group("/pinning")
pinning.Use(util.OpenApiMiddleware(s.log))
pinning.Use(s.AuthRequired(util.PermLevelUser))
pinning.GET("/pins", util.WithUser(s.handleListPins))
pinning.GET("/pins/:pinid", util.WithUser(s.handleGetPin))
pinning.DELETE("/pins/:pinid", util.WithUser(s.handleDeletePin))
pinning.GET("/pins", withUser(s.handleListPins))
pinning.GET("/pins/:pinid", withUser(s.handleGetPin))
pinning.DELETE("/pins/:pinid", withUser(s.handleDeletePin))
pinning.Use(util.JSONPayloadMiddleware)
pinning.POST("/pins", util.WithUser(s.handleAddPin))
pinning.POST("/pins/:pinid", util.WithUser(s.handleReplacePin))
pinning.POST("/pins", withUser(s.handleAddPin))
pinning.POST("/pins/:pinid", withUser(s.handleReplacePin))

// explicitly public, for now
public := e.Group("/public")
Expand Down Expand Up @@ -218,14 +221,14 @@ func (s *apiV1) RegisterRoutes(e *echo.Echo) {
admin.GET("/dealstats", s.handleDealStats)
admin.GET("/disk-info", s.handleDiskSpaceCheck)
admin.GET("/stats", s.handleAdminStats)
admin.GET("/system/config", util.WithUser(s.handleGetSystemConfig))
admin.GET("/system/config", withUser(s.handleGetSystemConfig))

// miners
admin.POST("/miners/add/:miner", s.handleAdminAddMiner)
admin.POST("/miners/rm/:miner", s.handleAdminRemoveMiner)
admin.POST("/miners/suspend/:miner", util.WithUser(s.handleSuspendMiner))
admin.PUT("/miners/unsuspend/:miner", util.WithUser(s.handleUnsuspendMiner))
admin.PUT("/miners/set-info/:miner", util.WithUser(s.handleMinersSetInfo))
admin.POST("/miners/suspend/:miner", withUser(s.handleSuspendMiner))
admin.PUT("/miners/unsuspend/:miner", withUser(s.handleUnsuspendMiner))
admin.PUT("/miners/set-info/:miner", withUser(s.handleMinersSetInfo))
admin.GET("/miners", s.handleAdminGetMiners)
admin.GET("/miners/stats", s.handleAdminGetMinerStats)
admin.GET("/miners/transfers/:miner", s.handleMinerTransferDiagnostics)
Expand Down Expand Up @@ -260,7 +263,7 @@ func (s *apiV1) RegisterRoutes(e *echo.Echo) {
admin.GET("/retrieval/querytest/:content", s.handleRetrievalCheck)
admin.GET("/retrieval/stats", s.handleGetRetrievalInfo)

admin.POST("/invite/:code", util.WithUser(s.handleAdminCreateInvite))
admin.POST("/invite/:code", withUser(s.handleAdminCreateInvite))
admin.GET("/invites", s.handleAdminGetInvites)

admin.GET("/fixdeals", s.handleFixupDeals)
Expand Down
78 changes: 59 additions & 19 deletions api/v1/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ type statsResp struct {
PinningStatus pinningtypes.PinningStatus `json:"pinningStatus"`
}

func withUser(f func(echo.Context, *util.User) error) func(echo.Context) error {
return func(c echo.Context) error {
u, ok := c.Get("user").(*util.User)
if !ok {
return &util.HttpError{
Code: http.StatusUnauthorized,
Reason: util.ERR_INVALID_AUTH,
Details: "endpoint not called with proper authentication",
}
}
return f(c, u)
}
}

// handleStats godoc
// @Summary Get content statistics
// @Description This endpoint is used to get content statistics. Every content stored in the network (estuary) is tracked by a unique ID which can be used to get information about the content. This endpoint will allow the consumer to get the collected stats of a content
Expand Down Expand Up @@ -570,7 +584,7 @@ func (s *apiV1) handleAdd(c echo.Context, u *util.User) error {
col = &srchCol
}

path, err := util.ConstructDirectoryPath(c.QueryParam(ColDir))
path, err := constructDirectoryPath(c.QueryParam(ColDir))
if err != nil {
return err
}
Expand Down Expand Up @@ -650,6 +664,20 @@ func (s *apiV1) handleAdd(c echo.Context, u *util.User) error {
})
}

func constructDirectoryPath(dir string) (string, error) {
defaultPath := "/"
path := defaultPath
if cp := dir; cp != "" {
sp, err := sanitizePath(cp)
if err != nil {
return "", err
}

path = sp
}
return path, nil
}

// redirectContentAdding is called when localContentAddingDisabled is true
// it finds available shuttles and adds the desired content in one of them
func (s *apiV1) redirectContentAdding(c echo.Context, u *util.User) error {
Expand Down Expand Up @@ -1784,7 +1812,7 @@ func (s *apiV1) handleAdminGetMinerStats(c echo.Context) error {
// @Description This endpoint lets a user set miner info.
// @Tags miner
// @Produce json
// @Success 200 {object} map[string]string{}
// @Success 200 {object} emptyResp
// @Failure 400 {object} util.HttpError
// @Failure 500 {object} util.HttpError
// @Param params body miner.MinerSetInfoParams true "Miner set info params"
Expand All @@ -1804,7 +1832,7 @@ func (s *apiV1) handleMinersSetInfo(c echo.Context, u *util.User) error {
if err := s.minerManager.SetMinerInfo(m, params, u); err != nil {
return err
}
return c.JSON(http.StatusOK, map[string]string{})
return c.JSON(http.StatusOK, emptyResp{})
}

func (s *apiV1) handleAdminRemoveMiner(c echo.Context) error {
Expand All @@ -1819,12 +1847,14 @@ func (s *apiV1) handleAdminRemoveMiner(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{})
}

type emptyResp struct{}

// handleSuspendMiner godoc
// @Summary Suspend Miner
// @Description This endpoint lets a user suspend a miner.
// @Tags miner
// @Produce json
// @Success 200 {object} map[string]string{}
// @Success 200 {object} emptyResp
// @Failure 400 {object} util.HttpError
// @Failure 500 {object} util.HttpError
// @Param req body miner.SuspendMinerBody true "Suspend Miner Body"
Expand All @@ -1844,15 +1874,15 @@ func (s *apiV1) handleSuspendMiner(c echo.Context, u *util.User) error {
if err := s.minerManager.SuspendMiner(m, body, u); err != nil {
return err
}
return c.JSON(http.StatusOK, nil)
return c.JSON(http.StatusOK, emptyResp{})
}

// handleUnsuspendMiner godoc
// @Summary Unuspend Miner
// @Description This endpoint lets a user unsuspend a miner.
// @Tags miner
// @Produce json
// @Success 200 {object} map[string]string{}
// @Success 200 {object} emptyResp
// @Failure 400 {object} util.HttpError
// @Failure 500 {object} util.HttpError
// @Param miner path string true "Miner to unsuspend"
Expand All @@ -1866,7 +1896,7 @@ func (s *apiV1) handleUnsuspendMiner(c echo.Context, u *util.User) error {
if err := s.minerManager.UnSuspendMiner(m, u); err != nil {
return err
}
return c.JSON(http.StatusOK, nil)
return c.JSON(http.StatusOK, emptyResp{})
}

func (s *apiV1) handleAdminAddMiner(c echo.Context) error {
Expand Down Expand Up @@ -3159,7 +3189,7 @@ func (s *apiV1) handleAddContentsToCollection(c echo.Context, u *util.User) erro
return fmt.Errorf("%d specified content(s) were not found or user missing permissions", len(contentIDs)-len(contents))
}

path, err := util.ConstructDirectoryPath(c.QueryParam(ColDir))
path, err := constructDirectoryPath(c.QueryParam(ColDir))
var colrefs []collections.CollectionRef
for _, cont := range contents {
fullPath := filepath.Join(path, cont.Name)
Expand Down Expand Up @@ -4551,7 +4581,7 @@ func (s *apiV1) handleCreateContent(c echo.Context, u *util.User) error {
req.CollectionDir = "/"
}

sp, err := util.SanitizePath(req.CollectionDir)
sp, err := sanitizePath(req.CollectionDir)
if err != nil {
return err
}
Expand Down Expand Up @@ -4946,15 +4976,25 @@ const (
ColDir string = "dir"
)

type collectionListResponse struct {
Name string `json:"name"`
Type CidType `json:"type"`
Size int64 `json:"size"`
ContID uint `json:"contId"`
Cid *util.DbCID `json:"cid,omitempty"`
Dir string `json:"dir"`
ColUuid string `json:"coluuid"`
UpdatedAt time.Time `json:"updatedAt"`
func sanitizePath(p string) (string, error) {
if len(p) == 0 {
return "", fmt.Errorf("can't sanitize empty path")
}

if p[0] != '/' {
return "", fmt.Errorf("paths must start with /")
}

// TODO: prevent use of special weird characters

cleanPath := filepath.Clean(p)

// if original path ends in /, append / to cleaned path
// needed for full path vs dir+filename magic to work in handleAddIpfs
if strings.HasSuffix(p, "/") {
cleanPath = cleanPath + "/"
}
return cleanPath, nil
}

// handleColfsAdd godoc
Expand Down Expand Up @@ -5008,7 +5048,7 @@ func (s *apiV1) handleColfsAdd(c echo.Context, u *util.User) error {

var path *string
if npath != "" {
p, err := util.SanitizePath(npath)
p, err := sanitizePath(npath)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion api/v1/pinning.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func (s *apiV1) handleAddPin(e echo.Context, u *util.User) error {
var colpath *string
colp, ok := pin.Meta["colpath"].(string)
if ok {
p, err := util.SanitizePath(colp)
p, err := sanitizePath(colp)
if err != nil {
return err
}
Expand Down
18 changes: 0 additions & 18 deletions api/v2/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/application-research/estuary/node"
"github.com/application-research/estuary/pinner"
"github.com/application-research/estuary/stagingbs"
"github.com/application-research/estuary/util"
"github.com/application-research/estuary/util/gateway"
"github.com/application-research/filclient"
"github.com/filecoin-project/lotus/api"
Expand Down Expand Up @@ -84,21 +83,4 @@ func NewAPIV2(
// @securityDefinitions.Bearer.name Authorization
func (s *apiV2) RegisterRoutes(e *echo.Echo) {
_ = e.Group("/v2")

// Storage Provider Endpoints
storageProvider := e.Group("/storage-providers")
storageProvider.POST("/add/:sp", s.handleAddStorageProvider, s.AuthRequired(util.PermLevelAdmin))
storageProvider.POST("/rm/:sp", s.handleRemoveStorageProvider, s.AuthRequired(util.PermLevelAdmin))
storageProvider.POST("/suspend/:sp", util.WithUser(s.handleSuspendStorageProvider))
storageProvider.PUT("/unsuspend/:sp", util.WithUser(s.handleUnsuspendStorageProvider))
storageProvider.PUT("/set-info/:sp", util.WithUser(s.handleStorageProvidersSetInfo))
storageProvider.GET("/stats", s.handleGetStorageProviderDealStats, s.AuthRequired(util.PermLevelAdmin))
storageProvider.GET("/transfers/:sp", s.handleStorageProviderTransferDiagnostics, s.AuthRequired(util.PermLevelAdmin))
storageProvider.GET("", s.handleGetStorageProviders)
storageProvider.GET("/failures/:sp", s.handleGetStorageProviderFailures)
storageProvider.GET("/deals/:sp", s.handleGetStorageProviderDeals)
storageProvider.GET("/stats/:sp", s.handleGetStorageProviderStats)
storageProvider.GET("/storage/query/:cid", s.handleStorageProviderQueryAsk)
storageProvider.POST("/claim", util.WithUser(s.handleClaimStorageProvider))
storageProvider.GET("/claim/:sp", util.WithUser(s.handleGetClaimStorageProviderMsg))
}
Loading