diff --git a/.env b/.env index 56e98ff..99557f8 100644 --- a/.env +++ b/.env @@ -2,19 +2,19 @@ API_SECRET=nyEX8BZ44KqTXeV2 # DB configuration DEVELOPMENT -API_PORT=8111 -API_RELEASE="Desenvolvimento" -DB_HOST=177.153.50.98 -DB_DRIVER=postgres -DB_USER=pcastdev -DB_PASSWORD=@407Smc837 -DB_NAME=pcastdev -DB_PORT=5432 +#API_PORT=8111 +#API_RELEASE="Desenvolvimento" +#DB_HOST=177.153.50.98 +#DB_DRIVER=postgres +#DB_USER=pcastdev +#DB_PASSWORD=@407Smc837 +#DB_NAME=pcastdev +#DB_PORT=5432 # DB configuration HOMOLOGAÇÃO #API_PORT=8111 #API_RELEASE="Homologação" -#DB_HOST=177.153.50.98 +#DB_HOST=191.252.214.157 #DB_DRIVER=postgres #DB_USER=pcasthomolog #DB_PASSWORD=@407Smc837 @@ -22,11 +22,11 @@ DB_PORT=5432 #DB_PORT=5432 # DB configuration PRODUÇÃO -#API_PORT=8112 -#API_RELEASE="" -#DB_HOST=177.153.50.98 -#DB_DRIVER=postgres -#DB_USER=pcast -#DB_PASSWORD=@407Smc837 -#DB_NAME=pcast -#DB_PORT=5432 \ No newline at end of file +API_PORT=8112 +API_RELEASE="" +DB_HOST=177.153.50.98 +DB_DRIVER=postgres +DB_USER=pcast +DB_PASSWORD=@407Smc837 +DB_NAME=pcast +DB_PORT=5432 diff --git a/.gitignore b/.gitignore index 69c27cc..9dd6d3d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ api api.exe +.env + pcast.db api-homolog.log .gitignore diff --git a/controllers/authController.go b/controllers/authController.go index a2aa3e0..0b02811 100644 --- a/controllers/authController.go +++ b/controllers/authController.go @@ -4,8 +4,10 @@ import ( "api/database" "api/models" "api/utils" + "log" "os" "strconv" + "strings" "time" "github.com/dgrijalva/jwt-go" @@ -19,6 +21,7 @@ func Login(c *fiber.Ctx) error { var data map[string]string if err := c.BodyParser(&data); err != nil { + log.Printf("Bad Request on parse: %v\n", err) return fiber.ErrBadRequest } @@ -27,11 +30,30 @@ func Login(c *fiber.Ctx) error { database.DB.Where("email = ?", data["email"]).First(&user) if user.Id == 0 { - return fiber.ErrNotFound + return c.JSON(fiber.Map{ + "message": "Usuário não encontrado", + "userId": 0, + "userType": "", + "userName": "", + "token": ""}) } if err := bcrypt.CompareHashAndPassword(user.Password, []byte(data["password"])); err != nil { - return fiber.ErrUnauthorized + return c.JSON(fiber.Map{ + "message": "Senha inválida", + "userId": 0, + "userType": "", + "userName": "", + "token": ""}) + } + + if user.Blocked == "S" { + return c.JSON(fiber.Map{ + "message": "Usuário bloqueado", + "userId": 0, + "userType": "", + "userName": "", + "token": ""}) } type customClaims struct { @@ -55,6 +77,7 @@ func Login(c *fiber.Ctx) error { } return c.JSON(fiber.Map{ + "message": "", "userId": user.Id, "userType": user.UserType, "userName": user.Name, @@ -67,44 +90,54 @@ func AddUser(c *fiber.Ctx) error { var data map[string]string if err := c.BodyParser(&data); err != nil { - return fiber.ErrBadRequest + return c.JSON(fiber.Map{ + "message": "Dados inválidos"}) + } - // If I don't receive an auth field in the request, I need to verify if the sender is logged - if data["auth"] == "" { - _, err := utils.ProcessToken(c) - if err != nil { - return fiber.ErrUnauthorized - } - } - - if data["name"] == "" || data["email"] == "" || data["password"] == "" || data["channel"] == "" { - return fiber.ErrBadRequest + if data["name"] == "" || data["email"] == "" || data["password"] == "" || data["channel"] == "" || data["usertype"] == "" || data["companyname"] == "" { + return c.JSON(fiber.Map{ + "message": "Dados inválidos"}) } passwd, _ := utils.HashPassword(data["password"]) - user := models.User{ + var user models.User + + database.DB.Where("email = ?", data["email"]).First(&user) + + if user.Id != 0 { + return c.JSON(fiber.Map{ + "message": "Usuário já cadastrado"}) + } + + database.DB.Where("channel = ?", strings.ToLower(data["channel"])).First(&user) + + if user.Id != 0 { + return c.JSON(fiber.Map{ + "message": "Canal já em uso"}) + } + + user = models.User{ Name: data["name"], Email: data["email"], CompanyName: data["companyname"], Password: passwd, - Channel: data["channel"], + Channel: strings.ToLower(data["channel"]), UserType: data["usertype"], Blocked: "N", Cancelled: "N", - CreatedBy: data["creator"], + CreatedBy: data["createdby"], } database.DB.Create(&user) if user.Id == 0 { - return fiber.ErrNotAcceptable + return c.JSON(fiber.Map{ + "message": "Erro ao criar usuário"}) } - return c.JSON(fiber.Map{ - "user": user, - }) + return c.JSON(user) } // GetOwnUser - Returns the current user @@ -146,3 +179,15 @@ func GetAllUsers(c *fiber.Ctx) error { return c.JSON(users) } + +func WixIntegration(c *fiber.Ctx) error { + var data map[string]string + + if err := c.BodyParser(&data); err != nil { + return fiber.ErrBadRequest + } + + utils.PrettyPrintJson(data) + + return c.JSON(data) +} diff --git a/controllers/eventController.go b/controllers/eventController.go index 78fb1c0..cab3784 100644 --- a/controllers/eventController.go +++ b/controllers/eventController.go @@ -57,7 +57,6 @@ func AddEvent(c *fiber.Ctx) error { Name: data["name"], Description: data["description"], UserId: user.Id, - Channel: user.Channel, ExpectedDate: startdt, EventType: data["eventtype"], } @@ -89,3 +88,29 @@ func GetAllEvents(c *fiber.Ctx) error { return c.JSON(events) } + +// GetEventsByUser - Returns all events from a user +func GetEventsByUser(c *fiber.Ctx) error { + + var events []models.Event + var user models.User + + _, err := utils.ProcessToken(c) + if err != nil { + return fiber.ErrUnauthorized + } + + database.DB.Where("id = ?", c.Params("id")).First(&user) + + if user.Id == 0 { + return fiber.ErrUnauthorized + } + + database.DB.Where("user_id = ?", user.Id).Find(&events) + + if len(events) == 0 { + return fiber.ErrNotFound + } + + return c.JSON(events) +} diff --git a/controllers/versionController.go b/controllers/versionController.go index 46a99f7..5ab5ff8 100644 --- a/controllers/versionController.go +++ b/controllers/versionController.go @@ -8,8 +8,8 @@ import ( func Version(c *fiber.Ctx) error { if globals.API_RELEASE == "" { - return c.JSON(globals.API_VERSION) + return c.SendString(globals.API_VERSION) } else { - return c.JSON(globals.API_VERSION + "-" + globals.API_RELEASE) + return c.SendString(globals.API_VERSION + "-" + globals.API_RELEASE) } } diff --git a/controllers/webhookController.go b/controllers/webhookController.go index 93dca44..c5c0c37 100644 --- a/controllers/webhookController.go +++ b/controllers/webhookController.go @@ -1,75 +1,73 @@ package controllers import ( - "fmt" + "api/models" + "api/utils" "log" "github.com/gofiber/fiber/v2" ) -type Pub struct { - Server string `json:"server_id"` - Protocol string `json:"protocol"` - Url string `json:"url"` - AppName string `json:"app_name"` - Channel string `json:"stream_name"` - UrlParam string `json:"url_param"` - RemoteAddress string `json:"remotet_addr"` - HasInSession bool `json:"has_in_session"` - HasOutSession bool `json:"has_out_session"` -} - -type Update struct { - Server string `json:"server_id"` - Groups []Group `json:"groups"` -} - -type Group struct { - Channel string `json:"stream_name"` - AudioCodec string `json:"audio_codec"` - VideoCodec string `json:"video_codec"` - VideoWidth int `json:"video_width"` - VideoHeight int `json:"video_height"` - UpdPub UpdPub `json:"pub"` - Subs string `json:"subs"` - UpdPull UpdPub `json:"pull"` -} - -type UpdPub struct { - Protocol string `json:"protocol"` - SessionId string `json:"session_id"` - RemoteAddress string `json:"remote_addr"` - StartTime string `json:"start_time"` - ReadBytesSum int `json:"read_bytes_sum"` - WroteBytesSum int `json:"wrote_bytes_sum"` - Bitrate int `json:"bitrate"` - ReadBitrate int `json:"read_bitrate"` - WriteBitrate int `json:"write_bitrate"` -} - func ServerStart(c *fiber.Ctx) error { - fmt.Println("Server started") - log.Println(string(c.Body())) + // Creates a server struct + s := new(models.LalServer) + + // Parse the body of the request to the server struct + if err := c.BodyParser(s); err != nil { + log.Printf("Error Start: %s\n", err) + return err + } + + log.Printf("Server started") + + // Marshal the server struct to JSON + utils.PrettyPrintJson(s) return c.SendString("Server started: " + string(c.Body())) } func OnUpdate(c *fiber.Ctx) error { - p := new(Update) + p := new(models.Update) if err := c.BodyParser(p); err != nil { log.Printf("Error Update: %s\n", err) return err } + log.Printf("Update") + utils.PrettyPrintJson(p) + if len(p.Groups) > 0 { for _, g := range p.Groups { log.Printf("Update %s %s [(%dx%d) %d]\n", g.Channel, g.UpdPub.StartTime, g.VideoWidth, g.VideoHeight, g.UpdPub.ReadBytesSum) } } + return c.SendString("On_Update: " + string(c.Body())) } +func OnSubStart(c *fiber.Ctx) error { + p := new(models.Update) + if err := c.BodyParser(p); err != nil { + log.Printf("Error SubStart: %s\n", err) + return err + } + + log.Printf("SubStart") + utils.PrettyPrintJson(p) + + // if len(p.Groups) > 0 { + // for _, g := range p.Groups { + // log.Printf("Update %s %s [(%dx%d) %d]\n", g.Channel, g.UpdPub.StartTime, g.VideoWidth, g.VideoHeight, g.UpdPub.ReadBytesSum) + // } + // } + + return c.SendString("On_Substart: " + string(c.Body())) +} + func OnPubStart(c *fiber.Ctx) error { - p := new(Pub) + // ================================================================ + // Called when a publisher starts streaming - Start of Transmission + // ================================================================ + p := new(models.Pub) if err := c.BodyParser(p); err != nil { return err } @@ -78,7 +76,10 @@ func OnPubStart(c *fiber.Ctx) error { } func OnPubStop(c *fiber.Ctx) error { - p := new(Pub) + // ============================================================= + // Called when a publisher stops streaming - End of Transmission + // ============================================================= + p := new(models.Pub) if err := c.BodyParser(p); err != nil { return err } diff --git a/database/database.go b/database/database.go index b9942c4..59836fa 100644 --- a/database/database.go +++ b/database/database.go @@ -86,7 +86,7 @@ func ConnectDB() error { Email: "pcast@pcast.com.br", CompanyName: "PCast", Password: passwd, - Channel: "PCast", + Channel: "pcast", UserType: "A", Blocked: "N", Cancelled: "N", diff --git a/globals/globals.go b/globals/globals.go index 37b1849..6eece97 100644 --- a/globals/globals.go +++ b/globals/globals.go @@ -1,6 +1,6 @@ package globals var ( - API_VERSION = "1.0.18" + API_VERSION = "1.0.21" API_RELEASE = "" ) diff --git a/index.html b/index.html new file mode 100644 index 0000000..86cf439 --- /dev/null +++ b/index.html @@ -0,0 +1,30 @@ + + + + + HLS.js Example + + + + + + + + + \ No newline at end of file diff --git a/infra/Caddyfile b/infra/Caddyfile index eb056c2..1daa984 100644 --- a/infra/Caddyfile +++ b/infra/Caddyfile @@ -6,12 +6,3 @@ http://www.pcastt.com.br, http://pcastt.com.br, https://www.pcastt.com.br, https reverse_proxy localhost:8111 } } - -http://www.pcastlive.com.br, http://pcastlive.com.br, https://www.pcastlive.com.br, https://pcastlive.com.br { - root * /root/sites/pcastlive - file_server - - handle_path /api/* { - reverse_proxy localhost:8112 - } -} diff --git a/infra/mqtt.service b/infra/mqtt.service new file mode 100644 index 0000000..855f3b3 --- /dev/null +++ b/infra/mqtt.service @@ -0,0 +1,12 @@ +[Unit] +Description=Mqtt Broker +After=multi-user.target + +[Service] +WorkingDirectory=/root/mqtt/cmd +ExecStart=/root/mqtt/cmd/mqtt +Type=simple + +[Install] +WantedBy=multi-user.target + diff --git a/infra/newapi.sh b/infra/newapi.sh index 709f37b..46bd5b8 100644 --- a/infra/newapi.sh +++ b/infra/newapi.sh @@ -1,4 +1,4 @@ service api stop cp /home/ftpuser/ftp/files/api /root/api -chmod 777 /root//api/api +chmod 777 /root/api/api service api start diff --git a/main.go b/main.go index 37a65ef..2348c69 100644 --- a/main.go +++ b/main.go @@ -14,47 +14,53 @@ import ( ) func main() { - logFile, err := os.OpenFile("api.log", os.O_CREATE | os.O_APPEND | os.O_RDWR, 0666) + logFile, err := os.OpenFile("api.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) if err != nil { - panic(err) + panic(err) } mw := io.MultiWriter(os.Stdout, logFile) log.SetOutput(mw) log.Println("Starting API", globals.API_VERSION) - log.Println("OS:", os.Getenv("OS")) - - app := fiber.New(fiber.Config{ - StrictRouting: false, - DisableStartupMessage: true, - }) - - app.Use(cors.New(cors.Config{ - AllowCredentials: true, - AllowOrigins: "http://*, https://*", - AllowHeaders: "Origin, Content-Type, Accept, Authorization, Access-Control-Allow-Origin", - AllowMethods: "GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS", - })) + log.Println("OS:", os.Getenv("OS")) file, err := os.OpenFile("./api-homolog.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { log.Fatalf("error opening file: %v", err) } - + defer file.Close() + app := fiber.New(fiber.Config{ + StrictRouting: false, + DisableStartupMessage: true, + }) + app.Use(logger.New(logger.Config{ Output: file, })) + app.Use(cors.New(cors.Config{ + AllowHeaders: "Origin,Content-Type,Accept,Content-Length,Accept-Language,Accept-Encoding,Connection,Access-Control-Allow-Origin", + AllowOrigins: "*", + AllowCredentials: true, + AllowMethods: "GET,POST,HEAD,PUT,DELETE,PATCH,OPTIONS", + })) + if err := database.ConnectDB(); err != nil { panic("Could not connect to database") } routes.Setup(app) + app.Use(func(c *fiber.Ctx) error { + return c.Status(fiber.StatusNotFound).SendString(c.BaseURL()) // => 404 "Not Found" + }) + log.Println("Server started in port " + os.Getenv("API_PORT")) - app.Listen(":" + os.Getenv("API_PORT")) + if erro := app.Listen(":" + os.Getenv("API_PORT")); err != nil { + panic(erro) + } } diff --git a/models/events.go b/models/events.go index 4c058e7..c695c30 100644 --- a/models/events.go +++ b/models/events.go @@ -8,7 +8,6 @@ type Event struct { Description string `gorm:"not null" json:"description"` ExpectedDate time.Time `gorm:"not null" json:"startDt"` UserId uint `gorm:"size:40;not null" json:"user"` - Channel string `gorm:"size:40;not null" json:"channel"` EventType string `gorm:"size:1;not null;default:O" json:"eventtype"` // O = Open, C = Closed Transmitted string `gorm:"size:1;not null;default:N" json:"transmitted"` // Y = Already transmitted, N = Not transmitted yet } diff --git a/models/users.go b/models/users.go index 6341d37..efcab15 100644 --- a/models/users.go +++ b/models/users.go @@ -8,6 +8,7 @@ type User struct { Password []byte `gorm:"size:100;not null;" json:"-"` Channel string `gorm:"size:40;not null" json:"channel"` UserType string `gorm:"size:1;not null;default:U" json:"usertype"` + Plan string `gorm:"size:1;not null;default:1" json:"T"` Blocked string `gorm:"size:1;not null;default:N" json:"blocked"` Cancelled string `gorm:"size:1;not null;default:N" json:"cancelled"` CreatedBy string `gorm:"size:15;not null;default:Manual" json:"createdby"` diff --git a/models/webhooks.go b/models/webhooks.go new file mode 100644 index 0000000..e43bc70 --- /dev/null +++ b/models/webhooks.go @@ -0,0 +1,51 @@ +package models + +type LalServer struct { + Server string `json:"server_id"` + BinInfo string `json:"-"` + LalVersion string `json:"lal_version"` + APIVersion string `json:"-"` + NotifyVersion string `json:"-"` + WebUIVersion string `json:"-"` + StartTime string `json:"start_time"` +} + +type Pub struct { + Server string `json:"server_id"` + Protocol string `json:"protocol"` + Url string `json:"url"` + AppName string `json:"app_name"` + Channel string `json:"stream_name"` + UrlParam string `json:"url_param"` + RemoteAddress string `json:"remotet_addr"` + HasInSession bool `json:"has_in_session"` + HasOutSession bool `json:"has_out_session"` +} + +type Update struct { + LalServer string `json:"server_id"` + Groups []Group `json:"groups"` +} + +type Group struct { + Channel string `json:"stream_name"` + AudioCodec string `json:"audio_codec"` + VideoCodec string `json:"video_codec"` + VideoWidth int `json:"video_width"` + VideoHeight int `json:"video_height"` + UpdPub UpdPub `json:"pub"` + Subs string `json:"subs"` + UpdPull UpdPub `json:"pull"` +} + +type UpdPub struct { + Protocol string `json:"protocol"` + SessionId string `json:"session_id"` + RemoteAddress string `json:"remote_addr"` + StartTime string `json:"start_time"` + ReadBytesSum int `json:"read_bytes_sum"` + WroteBytesSum int `json:"wrote_bytes_sum"` + Bitrate int `json:"bitrate"` + ReadBitrate int `json:"read_bitrate"` + WriteBitrate int `json:"write_bitrate"` +} diff --git a/routes/routes.go b/routes/routes.go index 7121172..6a505f3 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -12,6 +12,8 @@ import ( // Setup sets up the routes func Setup(app *fiber.App) { + app.Post("/integration", controllers.WixIntegration) + app.Get("/version", controllers.Version) app.Post("/login", controllers.Login) @@ -23,6 +25,7 @@ func Setup(app *fiber.App) { app.Post("/on_update", controllers.OnUpdate) app.Post("/on_pub_start", controllers.OnPubStart) app.Post("/on_pub_stop", controllers.OnPubStop) + app.Post("/on_sub_start", controllers.OnSubStart) // Protected routes. Needs login before. protected := app.Group("/") @@ -38,4 +41,6 @@ func Setup(app *fiber.App) { protected.Post("user", controllers.AddUser) protected.Post("event", controllers.AddEvent) + protected.Get("events", controllers.GetAllEvents) + protected.Get("events/:id", controllers.GetEventsByUser) } diff --git a/utils/utils.go b/utils/utils.go index 8fe1f87..dd02f79 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,7 +1,9 @@ package utils import ( + "encoding/json" "fmt" + "log" "os" "strings" @@ -61,3 +63,11 @@ func ProcessToken(c *fiber.Ctx) (interface{}, error) { func jwtKeyFunc(token *jwt.Token) (interface{}, error) { return []byte(os.Getenv("API_SECRET")), nil } + +func PrettyPrintJson(data interface{}) { + b, err := json.MarshalIndent(data, "", " ") + if err != nil { + fmt.Println("error:", err) + } + log.Println(string(b)) +}