completed test endpoint
parent
e4d1fb072a
commit
00f31d92ce
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
api
|
||||
api.exe
|
||||
*.exe
|
||||
|
||||
.env
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"api/database"
|
||||
"api/globals"
|
||||
"api/models"
|
||||
"api/services"
|
||||
"api/utils"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
|
@ -13,7 +12,7 @@ import (
|
|||
func GetUsers(c *fiber.Ctx) error {
|
||||
var users []models.SystemUser
|
||||
|
||||
database.DB.Find(&users)
|
||||
globals.DB.Find(&users)
|
||||
|
||||
return c.JSON(users)
|
||||
}
|
||||
|
|
@ -21,7 +20,7 @@ func GetUsers(c *fiber.Ctx) error {
|
|||
func GetGroups(c *fiber.Ctx) error {
|
||||
var groups []models.SystemGroup
|
||||
|
||||
database.DB.Find(&groups)
|
||||
globals.DB.Find(&groups)
|
||||
|
||||
return c.JSON(groups)
|
||||
}
|
||||
|
|
@ -41,7 +40,5 @@ func CreateUser(c *fiber.Ctx) error {
|
|||
fmt.Println("inexistent user")
|
||||
}
|
||||
|
||||
utils.SendEmail(email)
|
||||
|
||||
return c.JSON(user)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"api/globals"
|
||||
"api/models"
|
||||
"api/services"
|
||||
"api/utils"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
|
@ -126,9 +130,126 @@ func OnPubStop(c *fiber.Ctx) error {
|
|||
return c.SendString("On_Pub_Stop: " + string(c.Body()))
|
||||
}
|
||||
|
||||
type ResponseTest struct {
|
||||
Data DataTest `json:"data"`
|
||||
}
|
||||
|
||||
type DataTest struct {
|
||||
CNPJ string `json:"cnpj"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func WixTest(c *fiber.Ctx) error {
|
||||
log.Println(string(c.Body()))
|
||||
return c.SendString("On Test: " + string(c.Body()))
|
||||
|
||||
// Get the data from the callback
|
||||
var r ResponseTest
|
||||
if err := c.BodyParser(&r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Pass the data to variables
|
||||
cnpj := strings.TrimSpace(r.Data.CNPJ)
|
||||
name := strings.TrimSpace(r.Data.Name)
|
||||
email := strings.TrimSpace(r.Data.Email)
|
||||
|
||||
// Check if it is a valid CNPJ
|
||||
if !utils.IsValid(cnpj) {
|
||||
utils.SendTestEmail(email, name, "Foi informado um CNPJ inválido")
|
||||
return c.SendString("CNPJ Inválido")
|
||||
}
|
||||
|
||||
// Formats the CNPJ
|
||||
cnpjf := fmt.Sprintf("%s.%s.%s/%s-%s",
|
||||
cnpj[:2],
|
||||
cnpj[2:5],
|
||||
cnpj[5:8],
|
||||
cnpj[8:12],
|
||||
cnpj[12:])
|
||||
|
||||
// Let's see if it is a real CNPJ
|
||||
log.Printf("CNPJ %s [%s] requisitou um teste usando o email %s (%s)\n", cnpj, cnpjf, name, email)
|
||||
empresa := utils.GetEmpresa(cnpj)
|
||||
|
||||
if empresa.Situacao != "ATIVA" {
|
||||
utils.SendTestEmail(email, name, "Foi informado um CNPJ pertencente à uma empresa inativa")
|
||||
return c.SendString("Empresa inativa")
|
||||
}
|
||||
|
||||
// Let's see if its already on database
|
||||
customer := services.GetCustomerByCNPJ(cnpjf)
|
||||
|
||||
user := services.GetUserByEmail(email)
|
||||
|
||||
var userdb models.SystemUser
|
||||
var customerdb models.Customer
|
||||
|
||||
if user.ID == 0 {
|
||||
// Email not in database. Let's insert it
|
||||
userdb = models.SystemUser{
|
||||
Email: email,
|
||||
}
|
||||
|
||||
err := globals.DB.Create(&userdb)
|
||||
if err != nil {
|
||||
log.Printf("Cannot create test user: %v\n", err)
|
||||
}
|
||||
|
||||
user.ID = userdb.ID
|
||||
}
|
||||
|
||||
if customer.ID == 0 {
|
||||
// Inexistent customer; insert it into database
|
||||
customerwww := utils.GetEmpresa(cnpj)
|
||||
|
||||
customerdb = models.Customer{
|
||||
CNPJ: customerwww.CNPJ,
|
||||
Nome: customerwww.Nome,
|
||||
NomeFantasia: customerwww.Nome,
|
||||
Tipo: customerwww.Tipo,
|
||||
Porte: customerwww.Porte,
|
||||
Situacao: customerwww.Situacao,
|
||||
Abertura: customerwww.Abertura,
|
||||
NaturezaJuridica: customerwww.NaturezaJuridica,
|
||||
Logradouro: customerwww.Logradouro,
|
||||
Numero: customerwww.Numero,
|
||||
Complemento: customerwww.Complemento,
|
||||
Municipio: customerwww.Municipio,
|
||||
Bairro: customerwww.Bairro,
|
||||
UF: customerwww.UF,
|
||||
CEP: customerwww.CEP,
|
||||
UserID: user.ID,
|
||||
}
|
||||
|
||||
err := globals.DB.Create(&customerdb)
|
||||
if err.Error != nil {
|
||||
log.Printf("Cannot create test user: %v\n", err)
|
||||
}
|
||||
|
||||
// Now let's create the customer channel
|
||||
opts := utils.GenerationOptions{
|
||||
Length: 10,
|
||||
}
|
||||
|
||||
tkey, _ := utils.GenerateString(opts)
|
||||
|
||||
channel := models.Channel{
|
||||
Name: cnpj + "-01",
|
||||
TransmissionKey: tkey,
|
||||
CustomerID: customerdb.UserID,
|
||||
ServerID: 1,
|
||||
}
|
||||
err = globals.DB.Create(&channel)
|
||||
if err.Error != nil {
|
||||
log.Printf("Cannot create test channel: %v\n", err)
|
||||
}
|
||||
|
||||
// Finally, send an email
|
||||
utils.SendTestEmailApproval(email, name, "tkey", "url")
|
||||
|
||||
}
|
||||
|
||||
return c.SendString("On Test: " + empresa.Nome)
|
||||
}
|
||||
|
||||
func WixIntegration(c *fiber.Ctx) error {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package database
|
|||
|
||||
import (
|
||||
"api/config"
|
||||
"api/globals"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
|
|
@ -9,9 +10,6 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Our database
|
||||
var DB *gorm.DB
|
||||
|
||||
// ConnectDB - returns a pointer to a new database connection
|
||||
func ConnectDB() error {
|
||||
// var erre error
|
||||
|
|
@ -40,7 +38,7 @@ func ConnectDB() error {
|
|||
return err
|
||||
}
|
||||
|
||||
DB = db
|
||||
globals.DB = db
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
package globals
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
var (
|
||||
API_VERSION = ""
|
||||
API_RELEASE = ""
|
||||
|
||||
DB *gorm.DB
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package models
|
||||
|
||||
type Empresa struct {
|
||||
Abertura string `json:"abertura"`
|
||||
Situacao string `json:"situacao"`
|
||||
Tipo string `json:"tipo"`
|
||||
Nome string `json:"nome"`
|
||||
Porte string `json:"porte"`
|
||||
NaturezaJuridica string `json:"natureza_juridica"`
|
||||
AtividadePrincipal []Atividade `json:"atividade_principal"`
|
||||
AtividadesSecundarias []Atividade `json:"atividades_secundarias"`
|
||||
Logradouro string `json:"logradouro"`
|
||||
Numero string `json:"numero"`
|
||||
Complemento string `json:"complemento"`
|
||||
Municipio string `json:"municipio"`
|
||||
Bairro string `json:"bairro"`
|
||||
UF string `json:"uf"`
|
||||
CEP string `json:"cep"`
|
||||
Email string `json:"email"`
|
||||
Telefone string `json:"telefone"`
|
||||
DataSituacao string `json:"data_situacao"`
|
||||
CNPJ string `json:"cnpj"`
|
||||
UltimaAtualizacao string `json:"ultima_atualizacao"`
|
||||
Status string `json:"status"`
|
||||
Fantasia string `json:"fantasia"`
|
||||
EFR string `json:"efr"`
|
||||
MotivoSituacao string `json:"motivo_situacao"`
|
||||
SituacaoEspecial string `json:"situacao_especial"`
|
||||
DataSituacaoEspecial string `json:"data_situacao_especial"`
|
||||
CapitalSocial string `json:"capital_social"`
|
||||
QSA []interface{} `json:"qsa"`
|
||||
Simples Simples `json:"simples"`
|
||||
Simei Simei `json:"simei"`
|
||||
Extra map[string]interface{} `json:"extra"`
|
||||
Billing Billing `json:"billing"`
|
||||
}
|
||||
|
||||
type Atividade struct {
|
||||
Code string `json:"code"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type Simples struct {
|
||||
Optante bool `json:"optante"`
|
||||
DataOpcao string `json:"data_opcao"`
|
||||
DataExclusao string `json:"data_exclusao"`
|
||||
UltimaAtualizacao string `json:"ultima_atualizacao"`
|
||||
}
|
||||
|
||||
type Simei struct {
|
||||
Optante bool `json:"optante"`
|
||||
DataOpcao string `json:"data_opcao"`
|
||||
DataExclusao string `json:"data_exclusao"`
|
||||
UltimaAtualizacao string `json:"ultima_atualizacao"`
|
||||
}
|
||||
|
||||
type Billing struct {
|
||||
Free bool `json:"free"`
|
||||
Database bool `json:"database"`
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
package models
|
||||
|
||||
// ====================================================================
|
||||
// Adianti tables
|
||||
|
||||
type SystemGroup struct {
|
||||
ID int `gorm:"primaryKey"`
|
||||
Name string `gorm:"size:256"`
|
||||
|
|
@ -111,3 +114,41 @@ type SystemProgramMethodRole struct {
|
|||
SystemProgram SystemProgram `gorm:"foreignKey:SystemProgramID"`
|
||||
SystemRole SystemRole `gorm:"foreignKey:SystemRoleID"`
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// PCast tables
|
||||
|
||||
type Customer struct {
|
||||
ID int `gorm:"primaryKey;autoIncrement"`
|
||||
CNPJ string `gorm:"unique;not null"`
|
||||
Nome string `gorm:"not null"`
|
||||
NomeFantasia string `gorm:"not null"`
|
||||
Tipo string `gorm:"not null"`
|
||||
Porte string `gorm:"not null"`
|
||||
Situacao string `gorm:"not null"`
|
||||
Abertura string `gorm:"not null"`
|
||||
NaturezaJuridica string `gorm:"not null"`
|
||||
Logradouro string `gorm:"not null"`
|
||||
Numero string `gorm:"not null"`
|
||||
Complemento string `gorm:"not null"`
|
||||
Municipio string `gorm:"not null"`
|
||||
Bairro string `gorm:"not null"`
|
||||
UF string `gorm:"not null"`
|
||||
CEP string `gorm:"not null"`
|
||||
UserID int `gorm:"not null"`
|
||||
User SystemUser `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||
}
|
||||
|
||||
type Email struct {
|
||||
ID int
|
||||
Name string
|
||||
EmailText string
|
||||
}
|
||||
|
||||
type Channel struct {
|
||||
ID int
|
||||
Name string
|
||||
TransmissionKey string
|
||||
CustomerID int
|
||||
ServerID int
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,22 @@
|
|||
package services
|
||||
|
||||
import (
|
||||
"api/database"
|
||||
"api/globals"
|
||||
"api/models"
|
||||
)
|
||||
|
||||
func GetUserByEmail(email string) models.SystemUser {
|
||||
var user models.SystemUser
|
||||
|
||||
database.DB.Where("email = ?", email).Find(&user)
|
||||
globals.DB.Where("email = ?", email).Find(&user)
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
func GetCustomerByCNPJ(cnpj string) models.Customer {
|
||||
var user models.Customer
|
||||
|
||||
globals.DB.Where("cnpj = ?", cnpj).Find(&user)
|
||||
|
||||
return user
|
||||
}
|
||||
|
|
|
|||
226
utils/utils.go
226
utils/utils.go
|
|
@ -1,15 +1,106 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"api/globals"
|
||||
"api/models"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/gomail.v2"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type Charset string
|
||||
|
||||
const (
|
||||
Alphanumeric = Charset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
Lowercase = Charset("abcdefghijklmnopqrstuvwxyz")
|
||||
Uppercase = Charset("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
Numeric = Charset("0123456789")
|
||||
SpecialCharacters = Charset("!@#$%^&*()-_=+[]{}|;:'<>,.?/~")
|
||||
)
|
||||
|
||||
var (
|
||||
GenerateString = generateString
|
||||
)
|
||||
|
||||
type GenerationOptions struct {
|
||||
Length int
|
||||
DisableNumeric bool
|
||||
DisableLowercase bool
|
||||
DisableUppercase bool
|
||||
EnableSpecialCharacter bool
|
||||
CustomCharset Charset
|
||||
}
|
||||
|
||||
// generateStringFromCharset generates a random string from a given charset
|
||||
func generateStringFromCharset(charset Charset, length int) (string, error) {
|
||||
if len(charset) == 0 || length <= 0 {
|
||||
return "", errors.New("invalid charset or length")
|
||||
}
|
||||
|
||||
result := make([]byte, length)
|
||||
charsetLen := big.NewInt(int64(len(charset)))
|
||||
for i := 0; i < length; i++ {
|
||||
randomIndex, err := rand.Int(rand.Reader, charsetLen)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
result[i] = charset[randomIndex.Int64()]
|
||||
}
|
||||
|
||||
return string(result), nil
|
||||
}
|
||||
|
||||
// modifyCharset modifies the charset based on the options
|
||||
func modifyCharset(opts GenerationOptions, charsetMappings map[string]Charset, charset Charset) Charset {
|
||||
if opts.DisableNumeric {
|
||||
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["numeric"]), ""))
|
||||
}
|
||||
if opts.DisableLowercase {
|
||||
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["lowercase"]), ""))
|
||||
}
|
||||
if opts.DisableUppercase {
|
||||
charset = Charset(strings.ReplaceAll(string(charset), string(charsetMappings["uppercase"]), ""))
|
||||
}
|
||||
if opts.EnableSpecialCharacter {
|
||||
charset += charsetMappings["specialCharater"]
|
||||
}
|
||||
return charset
|
||||
}
|
||||
|
||||
// generateString generates a random string based on the options
|
||||
func generateString(opts GenerationOptions) (string, error) {
|
||||
charsetMappings := map[string]Charset{
|
||||
"numeric": Numeric,
|
||||
"lowercase": Lowercase,
|
||||
"uppercase": Uppercase,
|
||||
"specialCharater": SpecialCharacters,
|
||||
}
|
||||
|
||||
charset := Alphanumeric
|
||||
if opts.CustomCharset != "" {
|
||||
charset = opts.CustomCharset
|
||||
} else {
|
||||
charset = modifyCharset(opts, charsetMappings, charset)
|
||||
}
|
||||
|
||||
if len(charset) == 0 {
|
||||
return "", errors.New("resulting charset is empty. adjust your options")
|
||||
}
|
||||
|
||||
return generateStringFromCharset(charset, opts.Length)
|
||||
}
|
||||
|
||||
func HashPassword(password string) ([]byte, error) {
|
||||
return bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
}
|
||||
|
|
@ -22,12 +113,141 @@ func PrettyPrintJson(data interface{}) {
|
|||
log.Println(string(b))
|
||||
}
|
||||
|
||||
func SendEmail(email string) {
|
||||
// IsValid checks if a CNPJ is valid
|
||||
func IsValid(cnpj string) bool {
|
||||
// Remove non-numeric characters
|
||||
cnpj = removeNonDigits(cnpj)
|
||||
|
||||
if len(cnpj) != 14 || allDigitsEqual(cnpj) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate check digits
|
||||
return checkCNPJCheckDigits(cnpj)
|
||||
}
|
||||
|
||||
// removeNonDigits removes all non-numeric characters from a string
|
||||
func removeNonDigits(input string) string {
|
||||
var result strings.Builder
|
||||
for _, r := range input {
|
||||
if r >= '0' && r <= '9' {
|
||||
result.WriteRune(r)
|
||||
}
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// allDigitsEqual checks if all characters in a string are the same
|
||||
func allDigitsEqual(cnpj string) bool {
|
||||
for i := 1; i < len(cnpj); i++ {
|
||||
if cnpj[i] != cnpj[0] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// checkCNPJCheckDigits validates the two check digits of a CNPJ
|
||||
func checkCNPJCheckDigits(cnpj string) bool {
|
||||
weights1 := []int{5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}
|
||||
weights2 := []int{6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}
|
||||
|
||||
// Calculate first check digit
|
||||
digit1 := calculateCheckDigit(cnpj[:12], weights1)
|
||||
|
||||
// Calculate second check digit
|
||||
digit2 := calculateCheckDigit(cnpj[:13], weights2)
|
||||
|
||||
// Check if the calculated digits match the actual ones
|
||||
return cnpj[12] == digit1 && cnpj[13] == digit2
|
||||
}
|
||||
|
||||
// calculateCheckDigit calculates a single check digit for a given CNPJ slice and weight array
|
||||
func calculateCheckDigit(numbers string, weights []int) byte {
|
||||
sum := 0
|
||||
for i, weight := range weights {
|
||||
num, _ := strconv.Atoi(string(numbers[i]))
|
||||
sum += num * weight
|
||||
}
|
||||
|
||||
remainder := sum % 11
|
||||
if remainder < 2 {
|
||||
return '0'
|
||||
}
|
||||
return byte('0' + (11 - remainder))
|
||||
}
|
||||
|
||||
func GetEmpresa(cnpj string) models.Empresa {
|
||||
url := "https://receitaws.com.br/v1/cnpj/" + cnpj
|
||||
|
||||
// Call the external URL
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
fmt.Println("Error fetching data:", err)
|
||||
return models.Empresa{}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Read the response body
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading response:", err)
|
||||
return models.Empresa{}
|
||||
}
|
||||
|
||||
// Parse the JSON response into the struct
|
||||
var response models.Empresa
|
||||
err = json.Unmarshal(body, &response)
|
||||
if err != nil {
|
||||
fmt.Println("Error parsing JSON:", err)
|
||||
return models.Empresa{}
|
||||
}
|
||||
|
||||
// Print the parsed response
|
||||
return response
|
||||
}
|
||||
|
||||
func SendTestEmail(email, name, message string) {
|
||||
|
||||
var emaildb models.Email
|
||||
|
||||
globals.DB.First(&emaildb, "name = ?", "TESTE-ERRO")
|
||||
|
||||
errText := emaildb.EmailText
|
||||
|
||||
errText = strings.Replace(errText, "[[ERRO]]", message, -1)
|
||||
errText = strings.Replace(errText, "[[NOME]]", name, -1)
|
||||
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", "suporte@pcastlive.com")
|
||||
m.SetHeader("To", email)
|
||||
m.SetHeader("Subject", "Test Email from Go")
|
||||
m.SetBody("text/plain", "This is a test email sent from a Go application.")
|
||||
m.SetHeader("Subject", "Solicitação de teste da plataforma PCastLive")
|
||||
m.SetBody("text/html", errText)
|
||||
|
||||
d := gomail.NewDialer("smtp.kinghost.net", 465, "suporte@pcastlive.com", "@407Smc837")
|
||||
|
||||
if err := d.DialAndSend(m); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func SendTestEmailApproval(email, name, transmkey, url string) {
|
||||
|
||||
var emaildb models.Email
|
||||
|
||||
globals.DB.First(&emaildb, "name = ?", "TESTE-APROVADO")
|
||||
|
||||
errText := emaildb.EmailText
|
||||
|
||||
errText = strings.Replace(errText, "[[NOME]]", name, -1)
|
||||
errText = strings.Replace(errText, "[[TRANSMKEY]]", transmkey, -1)
|
||||
errText = strings.Replace(errText, "[[URL]]", url, -1)
|
||||
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", "suporte@pcastlive.com")
|
||||
m.SetHeader("To", email)
|
||||
m.SetHeader("Subject", "Solicitação de teste da plataforma PCastLive")
|
||||
m.SetBody("text/html", errText)
|
||||
|
||||
d := gomail.NewDialer("smtp.kinghost.net", 465, "suporte@pcastlive.com", "@407Smc837")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue