package main import ( "context" "fmt" "gitea.pena/PenaSide/common/encrypt" "gitea.pena/PenaSide/customer/internal/models" "github.com/caarlos0/env/v8" "github.com/gofiber/fiber/v2" "github.com/twmb/franz-go/pkg/kgo" "log" "regexp" "time" ) func main() { config, err := loadConfig() if err != nil { log.Fatalf("error loading config: %v", err) } err = validateNotEmpty(config) if err != nil { log.Fatalf("error validating config: %v", err) } urls := []string{ config.AuthMicroservice, config.HubadminMicroservice, config.CurrencyMicroservice, config.DiscountMicroservice, config.CodewordMicroservice, config.PaymentMicroservice, config.VerificationMicroservice, config.TemplategenMicroserviceURL, config.TrashLogHost, config.AdminURL, config.ExternalCfg.MailClientCfg.ApiUrl, } if err = validateURLs(urls); err != nil { log.Fatalf("error validating urls: %v", err) } // todo validate jwt if err = validateKafka(config.KafkaBrokers, config.KafkaTopic); err != nil { log.Fatalf("error validating kafka: %v", err) } if err = validateMail(config.ExternalCfg.MailClientCfg); err != nil { log.Fatalf("error validating smtp: %v", err) } if err = validateEncryptKeys(&config.ExternalCfg.EncryptCommon); err != nil { log.Fatalf("error validating encrypted: %v", err) } if err = validateTG(config.NotificationBotToken, config.NotificationRsPayChannel, config.NotificationChannel); err != nil { log.Fatalf("error validating tg enviroments: %v", err) } //todo mongo } func loadConfig() (*models.Config, error) { var config models.Config if err := env.Parse(&config); err != nil { return nil, err } return &config, nil } func validateURLs(urls []string) error { for index, u := range urls { if u == "" { return fmt.Errorf("empty url, index: %d", index) } // todo проверять урлы //if ip := net.Pa(u); ip == nil { // return fmt.Errorf("invalid url: %s", u) //} // todo check the liveness of these URLs, many services do not support } return nil } func validateKafka(brokers []string, topic string) error { if len(brokers) == 0 { return fmt.Errorf("kafka brokers is empty") } if topic == "" { return fmt.Errorf("kafka topic is empty") } for _, addr := range brokers { if addr == "" { return fmt.Errorf("empty kafka broker") } } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() kafkaTariffClient, err := kgo.NewClient( kgo.SeedBrokers(brokers...), kgo.ConsumeResetOffset(kgo.NewOffset().AtStart()), kgo.DefaultProduceTopic(topic), kgo.ConsumeTopics(topic), ) if err != nil { return err } defer kafkaTariffClient.Close() err = kafkaTariffClient.Ping(ctx) if err != nil { return err } return nil } func validateMail(cfg models.MailClientCfg) error { if cfg.MailAddress == "" { return fmt.Errorf("mail address is empty") } if cfg.ApiUrl == "" { return fmt.Errorf("mail api url is empty") } if cfg.ApiKey == "" { return fmt.Errorf("mail api key is empty") } if cfg.Sender == "" { return fmt.Errorf("mail sender is empty") } client := fiber.AcquireClient() req := client.Get("https://api.smtp.bz/v1/user") req.Set("Authorization", cfg.ApiKey) code, _, _ := req.Bytes() if code != fiber.StatusOK { return fmt.Errorf("invalid smtp code, no auth: %d", code) } return nil } func validateEncryptKeys(e *encrypt.Encrypt) error { codeWord := "ДАЙТЕ Jazz-у!" shifr, err := e.EncryptStr(codeWord) if err != nil { return err } deShifr, err := e.DecryptStr(shifr) if err != nil { return err } if deShifr != codeWord { return fmt.Errorf("invalid encrypt key") } return nil } func validateNotEmpty(config *models.Config) error { if config.ModuleLogger == "" { return fmt.Errorf("ModuleLogger is empty") } if config.ExternalCfg.EncryptCommon.PrivKey == "" { return fmt.Errorf("invalid private encrypt key") } if config.ExternalCfg.EncryptCommon.PubKey == "" { return fmt.Errorf("invalid publice encrypt key") } return nil } func validateTG(notificationBotToken string, notificationRsPayChannel int64, notificationChannel int64) error { if notificationBotToken == "" { return fmt.Errorf("notificationBotToken is empty") } // todo обдумать еще регулярку pattern := `^\d+:.+$` ok, err := regexp.MatchString(pattern, notificationBotToken) if err != nil { return fmt.Errorf("error validating notificationBotToken: %w", err) } if !ok { return fmt.Errorf("invalid notificationBotToken format") } if notificationChannel == 0 { return fmt.Errorf("notificationChannel is not set") } if notificationRsPayChannel == 0 { return fmt.Errorf("notificationRsPayChannel is not set") } return nil }