-
-
Error!
-
{form.message}!
-
+ {#if formResult?.status === 'error'}
+
+ Error:
+ {formResult.message}!
{/if}
- {#if form?.status === 'ok'}
-
-
-
Success!
-
{form.message}!
-
+ {#if formResult?.status === 'ok'}
+
+ Success:
+ {formResult.message}!
{/if}
{:else}
+
+ Processing...
+
{/if}
diff --git a/handler/response.go b/handler/response.go
index 7b9311f..71332c2 100644
--- a/handler/response.go
+++ b/handler/response.go
@@ -2,6 +2,7 @@ package handler
import (
"fmt"
+ "strconv"
"time"
"github.com/ditatompel/xmr-nodes/internal/database"
@@ -114,6 +115,36 @@ func Prober(c *fiber.Ctx) error {
})
}
+func AddNode(c *fiber.Ctx) error {
+ formPort := c.FormValue("port")
+ port, err := strconv.Atoi(formPort)
+ if err != nil {
+ return c.JSON(fiber.Map{
+ "status": "error",
+ "message": "Invalid port number",
+ "data": nil,
+ })
+ }
+
+ protocol := c.FormValue("protocol")
+ hostname := c.FormValue("hostname")
+
+ moneroRepo := repo.NewMoneroRepo(database.GetDB())
+ if err := moneroRepo.Add(protocol, hostname, uint(port)); err != nil {
+ return c.JSON(fiber.Map{
+ "status": "error",
+ "message": err.Error(),
+ "data": nil,
+ })
+ }
+
+ return c.JSON(fiber.Map{
+ "status": "ok",
+ "message": "Query Ok",
+ "data": nil,
+ })
+}
+
func Crons(c *fiber.Ctx) error {
cronRepo := repo.NewCron(database.GetDB())
diff --git a/handler/routes.go b/handler/routes.go
index 1940353..cae95e6 100644
--- a/handler/routes.go
+++ b/handler/routes.go
@@ -14,5 +14,6 @@ func V1Api(app *fiber.App) {
v1.Get("/prober", Prober)
v1.Post("/prober", Prober)
+ v1.Post("/nodes", AddNode)
v1.Get("/crons", Crons)
}
diff --git a/internal/repo/monero.go b/internal/repo/monero.go
new file mode 100644
index 0000000..6eb416a
--- /dev/null
+++ b/internal/repo/monero.go
@@ -0,0 +1,79 @@
+package repo
+
+import (
+ "encoding/json"
+ "errors"
+ "net"
+ "strings"
+ "time"
+
+ "github.com/ditatompel/xmr-nodes/internal/database"
+)
+
+type MoneroRepository interface {
+ Add(protocol string, host string, port uint) error
+}
+
+type MoneroRepo struct {
+ db *database.DB
+}
+
+func NewMoneroRepo(db *database.DB) MoneroRepository {
+ return &MoneroRepo{db}
+}
+
+func (repo *MoneroRepo) Add(protocol string, hostname string, port uint) error {
+ if protocol != "http" && protocol != "https" {
+ return errors.New("Invalid protocol, must one of or HTTP/HTTPS")
+ }
+
+ if port > 65535 || port < 1 {
+ return errors.New("Invalid port number")
+ }
+
+ is_tor := false
+ if strings.HasSuffix(hostname, ".onion") {
+ is_tor = true
+ }
+ ip := ""
+
+ if !is_tor {
+ hostIps, err := net.LookupIP(hostname)
+ if err != nil {
+ return err
+ }
+
+ hostIp := hostIps[0].To4()
+ if hostIp == nil {
+ return errors.New("Host IP is not IPv4")
+ }
+ if hostIp.IsPrivate() {
+ return errors.New("IP address is private")
+ }
+ if hostIp.IsLoopback() {
+ return errors.New("IP address is loopback address")
+ }
+
+ ip = hostIp.String()
+ }
+
+ check := `SELECT id FROM tbl_node WHERE protocol = ? AND hostname = ? AND port = ? LIMIT 1`
+ row, err := repo.db.Query(check, protocol, hostname, port)
+ if err != nil {
+ return err
+ }
+ defer row.Close()
+
+ if row.Next() {
+ return errors.New("Node already monitored")
+ }
+ statusDb, _ := json.Marshal([5]int{2, 2, 2, 2, 2})
+
+ query := `INSERT INTO tbl_node (protocol, hostname, port, is_tor, nettype, ip_addr, lat, lon, date_entered, last_checked, last_check_status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
+ _, err = repo.db.Exec(query, protocol, hostname, port, is_tor, "", ip, 0, 0, time.Now().Unix(), 0, string(statusDb))
+ if err != nil {
+ return err
+ }
+
+ return nil
+}