Skip to content

Commit

Permalink
feat(SPV-930): get all webhooks - endpoint for admin (#671)
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-4chain authored Aug 27, 2024
1 parent 42f706f commit 691f3c5
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 1 deletion.
1 change: 1 addition & 0 deletions actions/admin/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func NewHandler(appConfig *config.AppConfig, services *config.AppServices) route
adminGroup.POST("/xpubs/count", action.xpubsCount)
adminGroup.POST("/webhooks/subscriptions", action.subscribeWebhook)
adminGroup.DELETE("/webhooks/subscriptions", action.unsubscribeWebhook)
adminGroup.GET("/webhooks/subscriptions", action.getAllWebhooks)
})

return adminEndpoints
Expand Down
25 changes: 25 additions & 0 deletions actions/admin/webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/http"

"github.com/bitcoin-sv/spv-wallet/engine/spverrors"
"github.com/bitcoin-sv/spv-wallet/mappings"
"github.com/bitcoin-sv/spv-wallet/models"
"github.com/gin-gonic/gin"
)
Expand Down Expand Up @@ -59,3 +60,27 @@ func (a *Action) unsubscribeWebhook(c *gin.Context) {

c.JSON(http.StatusOK, true)
}

// getAllWebhooks will return all the stored webhooks
// @Summary Get All Webhooks
// @Description Get All Webhooks currently subscribed to
// @Tags Admin
// @Produce json
// @Success 200 {object} []models.Webhook "List of webhooks"
// @Failure 500 "Internal server error - Error while getting all webhooks"
// @Router /v1/admin/webhooks/subscriptions [get]
// @Security x-auth-xpub
func (a *Action) getAllWebhooks(c *gin.Context) {
wh, err := a.Services.SpvWalletEngine.GetWebhooks(c.Request.Context())
if err != nil {
spverrors.ErrorResponse(c, err, a.Services.Logger)
return
}

webhookDTOs := make([]*models.Webhook, len(wh))
for i, w := range wh {
webhookDTOs[i] = mappings.MapToWebhookContract(w)
}

c.JSON(http.StatusOK, webhookDTOs)
}
10 changes: 10 additions & 0 deletions engine/client_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ func (c *Client) UnsubscribeWebhook(ctx context.Context, url string) error {
return c.options.notifications.webhookManager.Unsubscribe(ctx, url)
}

// GetWebhooks returns all the webhooks stored in database
func (c *Client) GetWebhooks(ctx context.Context) ([]notifications.ModelWebhook, error) {
if c.options.notifications == nil || c.options.notifications.webhookManager == nil {
return nil, spverrors.ErrNotificationsDisabled
}

//nolint:wrapcheck //we're returning our custom errors
return c.options.notifications.webhookManager.GetAll(ctx)
}

// loadPaymailClient will load the Paymail client
func (c *Client) loadPaymailClient() (err error) {
// Only load if it's not set (the client can be overloaded)
Expand Down
2 changes: 1 addition & 1 deletion engine/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/bitcoin-sv/spv-wallet/engine/datastore"
"github.com/bitcoin-sv/spv-wallet/engine/metrics"
"github.com/bitcoin-sv/spv-wallet/engine/notifications"
// "github.com/bitcoin-sv/spv-wallet/engine/notifications"
"github.com/bitcoin-sv/spv-wallet/engine/taskmanager"
"github.com/mrz1836/go-cachestore"
"github.com/rs/zerolog"
Expand Down Expand Up @@ -211,4 +210,5 @@ type ClientInterface interface {
Metrics() (metrics *metrics.Metrics, enabled bool)
SubscribeWebhook(ctx context.Context, url, tokenHeader, token string) error
UnsubscribeWebhook(ctx context.Context, url string) error
GetWebhooks(ctx context.Context) ([]notifications.ModelWebhook, error)
}
10 changes: 10 additions & 0 deletions engine/notifications/webhook_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ func (w *WebhookManager) Unsubscribe(ctx context.Context, url string) error {
return nil
}

// GetAll returns all the webhooks stored in database
func (w *WebhookManager) GetAll(ctx context.Context) ([]ModelWebhook, error) {
webhooks, err := w.repository.GetAll(ctx)
if err != nil {
w.logger.Warn().Msgf("failed to get webhooks: %v", err)
return nil, spverrors.ErrWebhookGetAll
}
return webhooks, nil
}

func (w *WebhookManager) checkForUpdates() {
defer func() {
w.logger.Info().Msg("WebhookManager stopped")
Expand Down
3 changes: 3 additions & 0 deletions engine/spverrors/definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ var ErrWebhookUnsubscriptionFailed = models.SPVError{Message: "webhook unsubscri
// ErrWebhookSubscriptionNotFound is when cannot find webhook to unsubscribe
var ErrWebhookSubscriptionNotFound = models.SPVError{Message: "webhook subscription not found", StatusCode: 404, Code: "error-webhook-subscription-not-found"}

// ErrWebhookGetAll is when cannot get all the stored webhooks
var ErrWebhookGetAll = models.SPVError{Message: "cannot get all the stored webhooks", StatusCode: 500, Code: "error-webhook-get-all"}

// ErrNotificationsDisabled happens when the notifications are not enabled in the config
var ErrNotificationsDisabled = models.SPVError{Message: "notifications are disabled", StatusCode: 404, Code: "error-notifications-disabled"}

Expand Down
18 changes: 18 additions & 0 deletions mappings/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package mappings

import (
"github.com/bitcoin-sv/spv-wallet/engine/notifications"
"github.com/bitcoin-sv/spv-wallet/models"
)

// MapToWebhookContract will map the webhook model from spv-wallet engine to the spv-wallet-models contract
func MapToWebhookContract(w notifications.ModelWebhook) *models.Webhook {
if w == nil {
return nil
}

return &models.Webhook{
URL: w.GetURL(),
Banned: w.Banned(),
}
}
8 changes: 8 additions & 0 deletions models/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package models

// Webhook is a webhook model
// TokenHeader and TokenValue are not exposed because of security reasons
type Webhook struct {
URL string `json:"url"`
Banned bool `json:"banned"`
}

0 comments on commit 691f3c5

Please sign in to comment.