Skip to content

Commit

Permalink
add mail reporting route for infra pkg, add minor fixes, update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
krustowski committed Nov 11, 2024
1 parent 28e3212 commit f41b2a5
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

APP_NAME=swis-api
APP_ROOT=/opt/${APP_NAME}
APP_VERSION=5.18.1
APP_VERSION=5.18.2


#
Expand Down
74 changes: 73 additions & 1 deletion api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"name": "MIT",
"url": "https://github.com/vxn-dev/swis-api/blob/master/LICENSE"
},
"version": "5.18.1"
"version": "5.18.2"
},
"host": "swis-api-run-prod:8050",
"basePath": "/",
Expand Down Expand Up @@ -2360,6 +2360,37 @@
}
}
},
"/infra/domains/{key}/dmarc": {
"post": {
"description": "post domain mail report by key",
"produces": [
"application/json"
],
"tags": [
"infra"
],
"summary": "Post domain mail report by key",
"parameters": [
{
"description": "DMARC parsed report",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/pkg_infra.SimpleReport"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/pkg_infra.Domain"
}
}
}
}
},
"/infra/hosts": {
"get": {
"description": "get hosts list",
Expand Down Expand Up @@ -4775,6 +4806,13 @@
"registrar_name": {
"description": "Name of the current registrar",
"type": "string"
},
"reports": {
"description": "Parsed DMARC reports.",
"type": "array",
"items": {
"$ref": "#/definitions/pkg_infra.SimpleReport"
}
}
}
},
Expand Down Expand Up @@ -4986,6 +5024,40 @@
}
}
},
"pkg_infra.SimpleReport": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"domain": {
"type": "string"
},
"reporting_org": {
"type": "string"
},
"sources": {
"type": "array",
"items": {
"$ref": "#/definitions/pkg_infra.Source"
}
}
}
},
"pkg_infra.Source": {
"type": "object",
"properties": {
"dkim_selector": {
"type": "string"
},
"ip_address": {
"type": "string"
},
"mail_count": {
"type": "integer"
}
}
},
"pkg_infra.VMInstallConfig": {
"type": "object",
"properties": {
Expand Down
2 changes: 1 addition & 1 deletion cmd/swis-api/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @title swis-api (swapi) v5
// @version 5.18.1
// @version 5.18.2
// @description sakalWeb Information System v5 RESTful API documentation
// @termsOfService http://swagger.io/terms/

Expand Down
2 changes: 1 addition & 1 deletion pkg/core/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ func assertSubpackageType[T any](input interface{}, model T) (map[string]T, bool
return nil, false
}

//fmt.Printf("%s\n", reflect.TypeOf(value))
fmt.Printf("%s\n", reflect.TypeOf(value))

output[k] = value
}
Expand Down
33 changes: 16 additions & 17 deletions pkg/dish/controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package dish

import (
//"encoding/json"
"fmt"
"io"
"net/http"
"reflect"
"strconv"
"time"

Expand Down Expand Up @@ -55,11 +57,9 @@ var restorePackage = &core.RestorePackage{
},
}

/*
sockets
*/
//
// sockets
//

// @Summary Get all sockets list
// @Description get socket list, socket array
Expand Down Expand Up @@ -124,13 +124,16 @@ func GetSocketListPublic(ctx *gin.Context) {
rawSocketsMap, _ := CacheSockets.GetAll()

for _, rawSocket := range rawSocketsMap {
socket, ok := rawSocket.(Socket)
socket, ok := rawSocket.(*Socket)
if !ok {
fmt.Printf("cannot assert type: %s\n", reflect.TypeOf(rawSocketsMap))
fmt.Printf("rawSocket: %v\n", rawSocket)
fmt.Printf("Socket: %v\n", Socket{})
continue
}

if socket.Public {
exportedSockets[socket.ID] = socket
exportedSockets[socket.ID] = *socket
counter++
}
}
Expand Down Expand Up @@ -502,11 +505,9 @@ func GetSSEvents(ctx *gin.Context) {
return
}

/*
incidents
*/
//
// incidents
//

// GetIncidentList lists all available incidents
//
Expand Down Expand Up @@ -750,11 +751,9 @@ func GetIncidentListBySocketID(ctx *gin.Context) {
return
}

/*
streamer stats
*/
//
// streamer stats
//

// GetStreamerStats returns the SSE streamer statistics.
//
Expand Down
79 changes: 79 additions & 0 deletions pkg/infra/controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package infra
import (
"net/http"
"os"
"time"

"go.vxn.dev/swis/v5/pkg/core"

Expand Down Expand Up @@ -221,6 +222,84 @@ func PostDomainDeploymentByKey(ctx *gin.Context) {
return
}

// @Summary Post domain mail report by key
// @Description post domain mail report by key
// @Tags infra
// @Produce json
// @Param request body infra.SimpleReport true "DMARC parsed report"
// @Success 200 {object} infra.Domain
// @Router /infra/domains/{key}/dmarc [post]
func PostDomainMailReportByKey(ctx *gin.Context) {
key := ctx.Param("key")

rawDomain, ok := CacheDomains.Get(key)
if !ok {
ctx.IndentedJSON(http.StatusNotFound, gin.H{
"code": http.StatusNotFound,
"message": "domain not found by key",
"package": pkgName,
"key": key,
})
return
}

var domain Domain

domain, ok = rawDomain.(Domain)
if !ok {
ctx.IndentedJSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"message": "cannot assert Domain data type",
"package": pkgName,
"key": key,
})
return
}

var report SimpleReport

if err := ctx.BindJSON(&report); err != nil {
ctx.IndentedJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"error": err.Error(),
"key": key,
"message": "cannot bind input JSON stream",
"package": pkgName,
})
return
}

var newReports []SimpleReport

for _, oldReport := range domain.Reports {
if time.Now().Add(time.Hour * -25).After(oldReport.CreatedAt) {
continue
}

newReports = append(newReports, oldReport)
}

newReports = append(newReports, report)

if saved := CacheDomains.Set(key, domain); !saved {
ctx.IndentedJSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"key": key,
"message": "updated domain couldn't be saved to database",
"package": pkgName,
})
return
}

ctx.IndentedJSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"key": key,
"message": "domain mail report added successfully",
"package": pkgName,
})
return
}

/*
HOSTS CRUD
Expand Down
30 changes: 30 additions & 0 deletions pkg/infra/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ type Infrastructure struct {
Networks map[string]Network `json:"networks"`
}

//
// Domains
//

type Domain struct {
// Unique domain identifier.
ID string `json:"id" binding:"required" required:"true" readonly:"true"`
Expand All @@ -41,8 +45,30 @@ type Domain struct {

// Cloudflare Zone ID
CfZoneID string `json:"cf_zone_id"`

// Parsed DMARC reports.
Reports []SimpleReport `json:"reports"`
}

// Parsed and cherry-picked DMARC report for such domain.
type SimpleReport struct {
Domain string `json:"domain"`
ReportingOrg string `json:"reporting_org"`
Sources []Source `json:"sources"`
CreatedAt time.Time `json:"created_at"`
}

// Source part detail for the DMARC simple report.
type Source struct {
IPAddress string `json:"ip_address"`
MailCount int `json:"mail_count"`
DKIMSelector string `json:"dkim_selector"`
}

//
// Hosts
//

// High-level struct for batch []Host array importing.
type Hosts struct {
Hosts map[string]Host `json:"hosts"`
Expand Down Expand Up @@ -261,6 +287,10 @@ type VMInstallConfig struct {
BridgeName string `json:"bridge_name" yaml:"bridge_name"`
}

//
// Networks
//

type Network struct {
// Unique network's identifier.
ID string `json:"id" binding:"required" required:"true" readonly:"true"`
Expand Down
2 changes: 2 additions & 0 deletions pkg/infra/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func Routes(g *gin.RouterGroup) {
GetDomainByKey)
g.POST("/domains/:key/deployment",
PostDomainDeploymentByKey)
g.POST("/domains/:key/dmarc",
PostDomainMailReportByKey)
g.PUT("/domains/:key",
UpdateDomainByKey)
g.DELETE("/domains/:key",
Expand Down

0 comments on commit f41b2a5

Please sign in to comment.