Skip to content
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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ LOG_LEVEL=
METRICS_ENABLED=true
METRICS_HOST="[::]"
METRICS_PORT=4000
SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS=
SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS= # Event API is auto-disabled when this is empty
9 changes: 5 additions & 4 deletions common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import (
)

type Config struct {
KeyperHTTPURL *url.URL
SigningKey *ecdsa.PrivateKey
PublicKey *ecdsa.PublicKey
P2P *p2p.Config
KeyperHTTPURL *url.URL
SigningKey *ecdsa.PrivateKey
PublicKey *ecdsa.PublicKey
P2P *p2p.Config
DisableEventAPI bool // true when SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS is not configured; if true, event API endpoints are not registered
}

func NewConfig(keyperHTTPUrl string, signingKey *ecdsa.PrivateKey, p2pConfig *p2p.Config) (*Config, error) {
Expand Down
34 changes: 32 additions & 2 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down Expand Up @@ -193,6 +199,12 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down Expand Up @@ -258,6 +270,12 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down Expand Up @@ -288,8 +306,8 @@ const docTemplate = `{
},
{
"type": "string",
"description": "Identity prefix associated with the event identity registration.",
"name": "identityPrefix",
"description": "Identity associated with the event identity registration.",
"name": "identity",
"in": "query",
"required": true
}
Expand Down Expand Up @@ -324,6 +342,12 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down Expand Up @@ -378,6 +402,12 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down
34 changes: 32 additions & 2 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down Expand Up @@ -184,6 +190,12 @@
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down Expand Up @@ -249,6 +261,12 @@
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down Expand Up @@ -279,8 +297,8 @@
},
{
"type": "string",
"description": "Identity prefix associated with the event identity registration.",
"name": "identityPrefix",
"description": "Identity associated with the event identity registration.",
"name": "identity",
"in": "query",
"required": true
}
Expand Down Expand Up @@ -315,6 +333,12 @@
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down Expand Up @@ -369,6 +393,12 @@
"schema": {
"$ref": "#/definitions/error.Http"
}
},
"501": {
"description": "Event API is disabled on this deployment.",
"schema": {
"$ref": "#/definitions/error.Http"
}
}
}
}
Expand Down
24 changes: 22 additions & 2 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ paths:
description: Internal server error.
schema:
$ref: '#/definitions/error.Http'
"501":
description: Event API is disabled on this deployment.
schema:
$ref: '#/definitions/error.Http'
security:
- BearerAuth: []
summary: Allows clients to compile an event trigger definition string.
Expand Down Expand Up @@ -267,6 +271,10 @@ paths:
description: Internal server error.
schema:
$ref: '#/definitions/error.Http'
"501":
description: Event API is disabled on this deployment.
schema:
$ref: '#/definitions/error.Http'
security:
- BearerAuth: []
summary: Provides data necessary to allow event-based encryption.
Expand Down Expand Up @@ -311,6 +319,10 @@ paths:
description: Internal server error.
schema:
$ref: '#/definitions/error.Http'
"501":
description: Event API is disabled on this deployment.
schema:
$ref: '#/definitions/error.Http'
security:
- BearerAuth: []
summary: Get decryption key.
Expand All @@ -327,9 +339,9 @@ paths:
name: eon
required: true
type: integer
- description: Identity prefix associated with the event identity registration.
- description: Identity associated with the event identity registration.
in: query
name: identityPrefix
name: identity
required: true
type: string
produces:
Expand All @@ -356,6 +368,10 @@ paths:
description: Internal server error.
schema:
$ref: '#/definitions/error.Http'
"501":
description: Event API is disabled on this deployment.
schema:
$ref: '#/definitions/error.Http'
security:
- BearerAuth: []
summary: Get event identity registration expiration block number.
Expand Down Expand Up @@ -393,6 +409,10 @@ paths:
description: Internal server error.
schema:
$ref: '#/definitions/error.Http'
"501":
description: Event API is disabled on this deployment.
schema:
$ref: '#/definitions/error.Http'
security:
- BearerAuth: []
summary: Allows clients to register an event trigger identity.
Expand Down
28 changes: 28 additions & 0 deletions internal/middleware/event_api_guard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package middleware

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/shutter-network/shutter-api/common"
sherror "github.com/shutter-network/shutter-api/internal/error"
)

// EventAPIGuard returns 501 Not Implemented when DisableEventAPI is true
// (i.e., when SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS is not configured).
// When enabled, requests proceed to the event handlers.
func EventAPIGuard(config *common.Config) gin.HandlerFunc {
return func(ctx *gin.Context) {
if config.DisableEventAPI {
err := sherror.NewHttpError(
"Event API is disabled on this deployment",
"Event API is disabled on this deployment",
http.StatusNotImplemented,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new response is not reflected on the API docs, example here: https://github.com/shutter-network/shutter-api/blob/main/internal/service/crypto.go#L53 and in other endpoints.

)
ctx.Error(err)
ctx.Abort()
return
}
ctx.Next()
}
}
1 change: 1 addition & 0 deletions internal/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func NewRouter(
}

eventGroup := api.Group("/event")
eventGroup.Use(middleware.EventAPIGuard(config))
{
eventGroup.POST("/compile_trigger_definition", cryptoService.CompileEventTriggerDefinition)
eventGroup.POST("/register_identity", cryptoService.RegisterEventIdentity)
Expand Down
5 changes: 5 additions & 0 deletions internal/service/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func NewCryptoService(
// @Failure 404 {object} error.Http "Decryption key not found for the associated identity."
// @Failure 429 {object} error.Http "Too many requests. Rate limited."
// @Failure 500 {object} error.Http "Internal server error."
// @Failure 501 {object} error.Http "Event API is disabled on this deployment."
// @Security BearerAuth
// @Router /event/get_decryption_key [get]
func (svc *CryptoService) GetEventDecryptionKey(ctx *gin.Context) {
Expand Down Expand Up @@ -188,6 +189,7 @@ func (svc *CryptoService) GetDataForEncryptionTime(ctx *gin.Context) {
// @Failure 400 {object} error.Http "Invalid Get data for encryption request."
// @Failure 429 {object} error.Http "Too many requests. Rate limited."
// @Failure 500 {object} error.Http "Internal server error."
// @Failure 501 {object} error.Http "Event API is disabled on this deployment."
// @Security BearerAuth
// @Router /event/get_data_for_encryption [get]
func (svc *CryptoService) GetDataForEncryptionEvent(ctx *gin.Context) {
Expand Down Expand Up @@ -358,6 +360,7 @@ func (svc *CryptoService) DecryptCommitment(ctx *gin.Context) {
// @Failure 400 {object} error.Http "Invalid Event Data."
// @Failure 429 {object} error.Http "Too many requests. Rate limited."
// @Failure 500 {object} error.Http "Internal server error."
// @Failure 501 {object} error.Http "Event API is disabled on this deployment."
// @Security BearerAuth
// @Router /event/compile_trigger_definition [post]
func (svc *CryptoService) CompileEventTriggerDefinition(ctx *gin.Context) {
Expand Down Expand Up @@ -400,6 +403,7 @@ func CompileEventTriggerDefinition(ctx *gin.Context) {
// @Failure 400 {object} error.Http "Invalid Register identity request."
// @Failure 429 {object} error.Http "Too many requests. Rate limited."
// @Failure 500 {object} error.Http "Internal server error."
// @Failure 501 {object} error.Http "Event API is disabled on this deployment."
// @Security BearerAuth
// @Router /event/register_identity [post]
func (svc *CryptoService) RegisterEventIdentity(ctx *gin.Context) {
Expand Down Expand Up @@ -440,6 +444,7 @@ func (svc *CryptoService) RegisterEventIdentity(ctx *gin.Context) {
// @Failure 404 {object} error.Http "Event identity registration not found."
// @Failure 429 {object} error.Http "Too many requests. Rate limited."
// @Failure 500 {object} error.Http "Internal server error."
// @Failure 501 {object} error.Http "Event API is disabled on this deployment."
// @Security BearerAuth
// @Router /event/get_trigger_expiration_block [get]
func (svc *CryptoService) GetEventTriggerExpirationBlock(ctx *gin.Context) {
Expand Down
7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ func main() {
log.Err(err).Msg("unable to parse keyper http url")
return
}
// Disable event API if event registry contract address is invalid or empty or zero address
config.DisableEventAPI =
!common.IsHexAddress(shutterEventRegistryContractAddressStringified) ||
shutterEventRegistryContractAddress == (common.Address{})
if config.DisableEventAPI {
log.Info().Msg("Event API disabled: SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS not configured")
}
app := router.NewRouter(ctx, db, contract, client, config)
watcher := watcher.NewWatcher(config, db)
group, deferFn := service.RunBackground(ctx, watcher)
Expand Down
1 change: 1 addition & 0 deletions tests/integration/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (s *TestShutterService) SetupSuite() {

s.config, err = common.NewConfig(keyperHTTPUrl, signingKey, &p2pConfig)
s.Require().NoError(err)
s.config.DisableEventAPI = false

rpc_url := os.Getenv("RPC_URL")
s.ethClient, err = ethclient.Dial(rpc_url)
Expand Down