Skip to content

Commit

Permalink
Add security scan endpoint.
Browse files Browse the repository at this point in the history
  • Loading branch information
robinjhuang committed Jun 18, 2024
1 parent 0ba4833 commit a2a6472
Show file tree
Hide file tree
Showing 22 changed files with 380 additions and 37 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Or manually run:

### Generate Migration Files

Run this command to generate migration files needed for staging/prod database schema changes:
Run this command to generate migration files needed for staging/prod database schema changes:

```shell
atlas migrate diff migration \
Expand Down Expand Up @@ -101,6 +101,14 @@ https://github.com/deepmap/oapi-codegen/issues/795

Here are some common errors and how to resolve them.

### Security Scan

If you are calling the `security-scan` endpoint, you need to add the endpoint url to `docker-compose.yml` and then make sure you have the correct permissions to call that function.

Check the `security-scan` Cloud Function repo for instructions on how to do that with `gcloud`.

For non Comfy-Org contributors, you can use your own hosted function or just avoid touching this part. We keep the security scan code private to avoid exploiters taking advantage of it.

### Firebase Token Errors

Usually in localdev, we use dreamboothy-dev Firebase project for authentication. This conflicts with our machine creation logic because all of those machine images are in dreamboothy. TODO(robinhuang): Figure out a solution for this. Either we replicate things in dreamboothy-dev, or we pass project information separately when creating machine images.
Expand Down
10 changes: 6 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package config

type Config struct {
ProjectID string
DripEnv string
SlackRegistryChannelWebhook string
JWTSecret string
ProjectID string
DripEnv string
SlackRegistryChannelWebhook string
DiscordSecurityChannelWebhook string
JWTSecret string
SecretScannerURL string
}
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ services:
CORS_ORIGIN: "http://localhost:3000"
JWT_SECRET: 8zT9YknYUTZRVAkgov86gT1NLezTtwrd # test secret
LOG_LEVEL: info # Set the log level here
SECRET_SCANNER_URL: ""
111 changes: 101 additions & 10 deletions drip/api.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ent/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ent/nodeversion/nodeversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions ent/schema/node_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const (
NodeVersionStatusDeleted NodeVersionStatus = "deleted"
NodeVersionStatusBanned NodeVersionStatus = "banned"
NodeVersionStatusPending NodeVersionStatus = "pending"
NodeVersionStatusFlagged NodeVersionStatus = "flagged"
)

func (NodeVersionStatus) Values() (types []string) {
Expand All @@ -75,5 +76,6 @@ func (NodeVersionStatus) Values() (types []string) {
string(NodeVersionStatusBanned),
string(NodeVersionStatusDeleted),
string(NodeVersionStatusPending),
string(NodeVersionStatusFlagged),
}
}
71 changes: 71 additions & 0 deletions gateways/discord/discord.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package discord

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"registry-backend/config"
)

type DiscordService interface {
SendSecurityCouncilMessage(msg string) error
}

type DripDiscordService struct {
securityDiscordChannelWebhook string
config *config.Config
}

func NewDiscordService(config *config.Config) *DripDiscordService {
return &DripDiscordService{
config: config,
securityDiscordChannelWebhook: config.DiscordSecurityChannelWebhook,
}
}

type discordRequestBody struct {
Content string `json:"content"`
}

func (s *DripDiscordService) SendSecurityCouncilMessage(msg string) error {
if s.config.DripEnv == "prod" {
return sendDiscordNotification(msg, s.securityDiscordChannelWebhook)
} else {
println("Skipping sending message to Discord in non-prod environment. " + msg)
}
return nil
}

func sendDiscordNotification(msg string, discordWebhookURL string) error {
if discordWebhookURL == "" {
return fmt.Errorf("no Discord webhook URL provided, skipping sending message to Discord")
}

body, err := json.Marshal(discordRequestBody{Content: msg})
if err != nil {
return err
}

req, err := http.NewRequest(http.MethodPost, discordWebhookURL, bytes.NewBuffer(body))
if err != nil {
return err
}

req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}

defer resp.Body.Close()

if resp.StatusCode >= 400 {
// You can handle or log the HTTP error status code here
return fmt.Errorf("request to Discord returned error status: %d", resp.StatusCode)
}

return nil
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ require (
github.com/stretchr/testify v1.8.4
github.com/testcontainers/testcontainers-go v0.28.0
github.com/testcontainers/testcontainers-go/modules/postgres v0.28.0
google.golang.org/api v0.165.0
google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9
google.golang.org/protobuf v1.32.0
)
Expand Down Expand Up @@ -114,6 +113,7 @@ require (
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.18.0 // indirect
google.golang.org/api v0.165.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9 // indirect
Expand Down
3 changes: 2 additions & 1 deletion integration-tests/ban_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ func TestBan(t *testing.T) {
// Initialize the Service
mockStorageService := new(gateways.MockStorageService)
mockSlackService := new(gateways.MockSlackService)
mockDiscordService := new(gateways.MockDiscordService)
mockSlackService.
On("SendRegistryMessageToSlack", mock.Anything).
Return(nil) // Do nothing for all slack messsage calls.

impl := implementation.NewStrictServerImplementation(
client, &config.Config{}, mockStorageService, mockSlackService)
client, &config.Config{}, mockStorageService, mockSlackService, mockDiscordService)

authz := drip_authorization.NewAuthorizationManager(client, impl.RegistryService).AuthorizationMiddleware()

Expand Down
3 changes: 2 additions & 1 deletion integration-tests/ci_cd_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ func TestCICD(t *testing.T) {
// Initialize the Service
mockStorageService := new(gateways.MockStorageService)
mockSlackService := new(gateways.MockSlackService)
mockDiscordService := new(gateways.MockDiscordService)
mockSlackService.
On("SendRegistryMessageToSlack", mock.Anything).
Return(nil) // Do nothing for all slack messsage calls.
impl := implementation.NewStrictServerImplementation(
client, &config.Config{}, mockStorageService, mockSlackService)
client, &config.Config{}, mockStorageService, mockSlackService, mockDiscordService)

ctx := context.Background()
now := time.Now()
Expand Down
3 changes: 2 additions & 1 deletion integration-tests/registry_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ func TestRegistry(t *testing.T) {
// Initialize the Service
mockStorageService := new(gateways.MockStorageService)
mockSlackService := new(gateways.MockSlackService)
mockDiscordService := new(gateways.MockDiscordService)
mockSlackService.
On("SendRegistryMessageToSlack", mock.Anything).
Return(nil) // Do nothing for all slack messsage calls.
impl := implementation.NewStrictServerImplementation(
client, &config.Config{}, mockStorageService, mockSlackService)
client, &config.Config{}, mockStorageService, mockSlackService, mockDiscordService)
authz := drip_authorization.NewAuthorizationManager(client, impl.RegistryService).
AuthorizationMiddleware()

Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func main() {
DripEnv: os.Getenv("DRIP_ENV"),
SlackRegistryChannelWebhook: os.Getenv("SLACK_REGISTRY_CHANNEL_WEBHOOK"),
JWTSecret: os.Getenv("JWT_SECRET"),
SecretScannerURL: os.Getenv("SECRET_SCANNER_URL"),
}

var dsn string
Expand Down
14 changes: 14 additions & 0 deletions mock/gateways/mock_discord_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package gateways

import (
"github.com/stretchr/testify/mock"
)

type MockDiscordService struct {
mock.Mock
}

func (m *MockDiscordService) SendSecurityCouncilMessage(msg string) error {
args := m.Called(msg)
return args.Error(0)
}
Loading

0 comments on commit a2a6472

Please sign in to comment.