Files
houston-be/cmd/app/server.go
Gullipalli Chetan Kumar 6b44ec9ec3 TP-43103 : Synch users data from slack to database and exposed api to return a list of bot users (#228)
* TP-42310| created api service to get list of slackbots (#215)

* TP-42310| created api service to get list of slackbots

* minor bug fix in GetAllHoustonUserBots function

* Synch users to db (#213)

* TP-43103| added event listeners to user detail changes and saving to db

* TP-43103| refactored the upsert users scheduler

* TP-43103| fixed updating users when deactivated in scheduler

* TP-43103| Made the requested changes

* added info loggers to user change events

* made changes to process only navi workspace user changes

* made addressed changes in pr and returning Real name in GetAllHoustonUserBots api

* resolved merge conflicts
2023-10-20 13:05:40 +05:30

256 lines
9.3 KiB
Go

package app
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
"go.uber.org/zap"
"gorm.io/gorm"
"houston/cmd/app/handler"
"houston/internal/clients"
"houston/internal/metrics"
"houston/model/ingester"
"houston/pkg/slackbot"
"houston/service"
"net/http"
"strings"
"time"
)
type Server struct {
gin *gin.Engine
logger *zap.Logger
db *gorm.DB
mjolnirClient *clients.MjolnirClient
}
func NewServer(gin *gin.Engine, logger *zap.Logger, db *gorm.DB, mjolnirClient *clients.MjolnirClient) *Server {
return &Server{
gin: gin,
logger: logger,
db: db,
mjolnirClient: mjolnirClient,
}
}
func (s *Server) Handler(houstonGroup *gin.RouterGroup) {
s.readinessHandler(houstonGroup)
s.gin.Use(s.metricMiddleware())
s.incidentClientHandler(houstonGroup)
s.incidentClientHandlerV2(houstonGroup)
s.filtersHandlerV2(houstonGroup)
s.gin.Use(s.createMiddleware())
s.teamHandler(houstonGroup)
s.severityHandler(houstonGroup)
s.incidentHandler(houstonGroup)
s.logHandler(houstonGroup)
s.usersHandler(houstonGroup)
s.filtersHandler(houstonGroup)
metrics.AdminHandler()
//this should always be at the end since it opens websocket to connect to slackbot
s.houstonHandler()
}
func (s *Server) houstonHandler() {
houstonClient := NewHoustonClient(s.logger)
houstonHandler := handler.NewSlackHandler(s.logger, s.db, houstonClient.socketModeClient)
houstonHandler.HoustonConnect()
}
func (s *Server) teamHandler(houstonGroup *gin.RouterGroup) {
houstonClient := NewHoustonClient(s.logger)
slackClient := slackbot.NewSlackClient(s.logger, houstonClient.socketModeClient)
authService := service.NewAuthService(s.mjolnirClient, slackClient, s.logger)
teamHandler := service.NewTeamService(s.gin, s.logger, s.db, slackClient, authService)
//Will be deprecated because they are not using houston group
s.gin.GET("/teams", teamHandler.GetTeams)
s.gin.GET("/teams/:id", teamHandler.GetTeams)
s.gin.POST("/teams", teamHandler.UpdateTeam)
houstonGroup.POST("/teams/add", teamHandler.AddTeam)
houstonGroup.GET("/teams", teamHandler.GetTeams)
houstonGroup.GET("/teams/:id", teamHandler.GetTeams)
houstonGroup.POST("/teams", teamHandler.UpdateTeam)
houstonGroup.PATCH("/teams/:id/manager/:userId", teamHandler.MakeManager)
houstonGroup.DELETE("/teams/:id/members/:userId", teamHandler.RemoveTeamMember)
houstonGroup.DELETE("/teams/:id", teamHandler.RemoveTeam)
}
func (s *Server) severityHandler(houstonGroup *gin.RouterGroup) {
houstonClient := NewHoustonClient(s.logger)
slackClient := slackbot.NewSlackClient(s.logger, houstonClient.socketModeClient)
severityHandler := service.NewSeverityService(s.gin, s.logger, s.db, slackClient)
//Will be deprecated because they are not using hosuton group
s.gin.GET("/severities", severityHandler.GetSeverities)
s.gin.GET("/severities/:id", severityHandler.GetSeverities)
s.gin.POST("/severities", severityHandler.UpdateSeverities)
houstonGroup.GET("/severities", severityHandler.GetSeverities)
houstonGroup.GET("/severities/:id", severityHandler.GetSeverities)
houstonGroup.POST("/severities", severityHandler.UpdateSeverities)
}
func (s *Server) incidentClientHandler(houstonGroup *gin.RouterGroup) {
houstonClient := NewHoustonClient(s.logger)
incidentHandler := service.NewIncidentService(s.gin, s.logger, s.db, houstonClient.socketModeClient)
// Add a header to the routes in houstonGroup
houstonGroup.Use(func(c *gin.Context) {
// Add your desired header key-value pair
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, PATCH, GET, PUT, DELETE")
c.Writer.Header().Set("Access-Control-Allow-Headers", viper.GetString("allowed.custom.headers"))
origin := c.Request.Header.Get("Origin")
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
})
//Will be deprecated because they are not using hosuton group
s.gin.POST("/create-incident", incidentHandler.CreateIncident)
//TODO- Remove these api. Provide Multi Realm support in Internal Web BFF
houstonGroup.GET("/incidents/unsecured/v2/:id", incidentHandler.GetIncidents)
houstonGroup.POST("/create-incident", incidentHandler.CreateIncident)
}
func (s *Server) incidentClientHandlerV2(houstonGroup *gin.RouterGroup) {
houstonGroup.Use(func(c *gin.Context) {
// Add your desired header key-value pair
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
c.Writer.Header().Set("Access-Control-Allow-Headers", viper.GetString("allowed.custom.headers"))
origin := c.Request.Header.Get("Origin")
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
})
incidentHandler := handler.NewIncidentHandler(s.gin, s.logger, s.db)
houstonGroup.POST("/create-incident-v2", incidentHandler.HandleCreateIncident)
}
func (s *Server) incidentHandler(houstonGroup *gin.RouterGroup) {
houstonClient := NewHoustonClient(s.logger)
incidentHandler := service.NewIncidentService(s.gin, s.logger, s.db, houstonClient.socketModeClient)
//Will be deprecated because they are not using hosuton group
s.gin.GET("/incidents", incidentHandler.GetIncidents)
s.gin.GET("/incidents/:id", incidentHandler.GetIncidents)
s.gin.POST("/incidents", incidentHandler.UpdateIncident)
s.gin.GET("/incidents/header", incidentHandler.GetIncidentHeader)
houstonGroup.GET("/incidents", incidentHandler.GetIncidents)
houstonGroup.GET("/incidents/:id", incidentHandler.GetIncidents)
houstonGroup.POST("/incidents", incidentHandler.UpdateIncident)
houstonGroup.GET("/incidents/header", incidentHandler.GetIncidentHeader)
houstonGroup.GET("/teamIncidents/:teamId", incidentHandler.GetTeamIncidents)
}
func (s *Server) logHandler(houstonGroup *gin.RouterGroup) {
logHandler := service.NewLogService(s.gin, s.logger, s.db)
houstonGroup.GET("/logs/:log_type/:id", logHandler.GetLogs)
}
func (s *Server) usersHandler(houstonGroup *gin.RouterGroup) {
houstonClient := NewHoustonClient(s.logger)
slackClient := slackbot.NewSlackClient(s.logger, houstonClient.socketModeClient)
authService := service.NewAuthService(s.mjolnirClient, slackClient, s.logger)
usersHandler := service.NewUserService(s.gin, s.logger, slackClient, s.db, houstonClient.socketModeClient, authService)
//Will be deprecated because they are not using hosuton group
s.gin.GET("/users/:id", usersHandler.GetUserInfo)
s.gin.GET("/users", usersHandler.GetUsersInConversation)
houstonGroup.GET("/users/:id", usersHandler.GetUserInfo)
houstonGroup.GET("/users", usersHandler.GetUsersInConversation)
houstonGroup.GET("/users/update", usersHandler.UpdateHoustonUsers)
houstonGroup.GET("/bots", usersHandler.GetAllHoustonUserBots)
}
func (s *Server) filtersHandler(houstonGroup *gin.RouterGroup) {
filtersHandler := service.NewFilterService(s.gin, s.logger, s.db)
//Will be deprecated because they are not using hosuton group
s.gin.GET("/filters", filtersHandler.GetFilters)
houstonGroup.GET("/filters", filtersHandler.GetFilters)
}
// to be removed via internal bff
func (s *Server) filtersHandlerV2(houstonGroup *gin.RouterGroup) {
filtersHandler := service.NewFilterService(s.gin, s.logger, s.db)
houstonGroup.GET("/filters/v2", filtersHandler.GetFilters)
}
func (s *Server) readinessHandler(houstonGroup *gin.RouterGroup) {
readinessHandler := service.NewReadinessService(s.gin)
//Will be deprecated because they are not using hosuton group
s.gin.GET("/ping", readinessHandler.Ping)
houstonGroup.GET("/ping", readinessHandler.Ping)
}
func (s *Server) Start() {
s.logger.Info("starting houston server", zap.String("port", viper.GetString("port")))
s.gin.Run(fmt.Sprintf(":%v", "8080"))
}
func (s *Server) metricMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
startTime := time.Now()
c.Next()
endTime := time.Now()
duration := endTime.Sub(startTime)
metricsPublisher := metrics.NewMetricPublisher()
apiMetrics := ingester.ApiMetric{
Url: c.Request.URL.Path,
Method: c.Request.Method,
ResponseCode: c.Writer.Status(),
StartTime: startTime.Unix(),
EndTime: endTime.Unix(),
DurationInMs: duration.Milliseconds(),
BytesSent: c.Writer.Size(),
}
metricsPublisher.PublishMetrics(ingester.MetricAttributes{ApiMetric: apiMetrics}, ingester.API_METRICS)
}
}
func (s *Server) createMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
whitelistedDomains := getWhitelistedDomains()
//auth handling
isAuthEnabled := viper.GetBool("auth.enabled")
if isAuthEnabled {
sessionResponse, err := s.mjolnirClient.GetSessionResponse(c.Request.Header.Get("X-Session-Token"))
if err != nil || sessionResponse.StatusCode == 401 {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
}
//cors handling
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, PATCH, DELETE, OPTIONS, GET, PUT")
c.Writer.Header().Set("Access-Control-Allow-Headers", viper.GetString("allowed.custom.headers"))
origin := c.Request.Header.Get("Origin")
if !whitelistedDomains[origin] {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(http.StatusOK)
return
}
}
}
func getWhitelistedDomains() map[string]bool {
allowedList := make(map[string]bool)
domains := strings.Split(viper.GetString("whitelisted.domains"), ",")
for _, domain := range domains {
domainLocal := domain
allowedList[domainLocal] = true
}
return allowedList
}