package main import ( "context" "crypto/tls" "fmt" "io" "log" "net/http" "github.com/gin-gonic/gin" "gorm.io/gorm" "src.whiteboxsystems.nl/decozo/okapidemo/dvzaservice/model" "src.whiteboxsystems.nl/decozo/okapidemo/sharedmodel" ) type UIService struct { srv *http.Server inited bool data *gorm.DB clientCert tls.Certificate } func (srv *UIService) LoadData(location string) error { var err error srv.data, err = model.GetDB(location) return err } func (srv *UIService) Addr() string { if srv.srv == nil { return "" } return srv.srv.Addr } func (srv *UIService) ListenAndServe() error { if !srv.inited { srv.init() } log.Printf("Listening on %v\n", srv.srv.Addr) return srv.srv.ListenAndServe() } func (srv *UIService) Shutdown(ctx context.Context) error { return srv.srv.Shutdown(ctx) } func (srv *UIService) init() { r := srv.srv.Handler.(*gin.Engine) r.LoadHTMLGlob("templates/*") r.Static("/assets", "./assets") r.Use(srv.Authenticate) r.GET("/", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "/ui") }) r.GET("/ui", srv.GetIndex) r.GET("/ui/*page", srv.GetIndex) r.GET("/api/connections", srv.GetConnections) r.GET("/api/connections/:connID", srv.GetConnection) r.GET("/api/connections/:connID/:serviceID", srv.GetSubscriptions) r.GET("/api/connections/:connID/:serviceID/:patientID", srv.GetPatient) r.GET("/api/registrations", srv.GetRegistrations) // r.GET("/api/systems/:sysid/patients", srv.GetPatients) // r.GET("/api/systems/:sysid/patients/:patid", srv.GetPatient) srv.inited = true } func (srv *UIService) GetIndex(c *gin.Context) { c.HTML(http.StatusOK, "index.html", gin.H{"externalURL": extRpcAddr}) } func (srv *UIService) GetConnection(c *gin.Context) { connID := c.Param("connID") connection := &sharedmodel.Connection{} srv.data.Where("id = ?", connID).Find(&connection) c.JSON(http.StatusOK, connection) } func (srv *UIService) GetSubscriptions(c *gin.Context) { connID := c.Param("connID") serviceID := c.Param("serviceID") serviceConfig := &sharedmodel.ServiceConfig{} srv.data.Preload("Service").Preload("Subscriptions").Where("connection_id = ? and id = ?", connID, serviceID).Find(&serviceConfig) c.JSON(http.StatusOK, serviceConfig) } func (srv *UIService) GetPatient(c *gin.Context) { connID := c.Param("connID") serviceID := c.Param("serviceID") patientID := c.Param("patientID") patient := &sharedmodel.Subscription{} serviceConfig := &sharedmodel.ServiceConfig{} srv.data.Preload("FetchProtocol").Preload("FetchProtocol.AuthConfig").Preload("Service").Where("connection_id = ? and id = ?", connID, serviceID).Find(&serviceConfig) srv.data.Where("service_config_id = ? and id = ?", serviceID, patientID).Find(&patient) protoconfig := map[string]string{} protometa := map[string]string{} err := serviceConfig.FetchProtocol.UnmarshalConfig(&protoconfig) if err != nil { c.AbortWithStatus(http.StatusBadRequest) return } err = patient.GetProtocolMeta(&protometa) if err != nil { c.AbortWithStatus(http.StatusBadRequest) return } url := fmt.Sprintf("%v?id=%v", protoconfig["url"], protometa["patientID"]) req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Authorization", serviceConfig.FetchProtocol.AuthConfig.Raw) client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, }, } resp, err := client.Do(req) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) return } if resp.StatusCode >= 400 { c.AbortWithError(resp.StatusCode, fmt.Errorf("%v", resp.Status)) return } io.Copy(c.Writer, resp.Body) } func (srv *UIService) Authenticate(c *gin.Context) { // Maybe authenticate user } func (srv *UIService) GetConnections(c *gin.Context) { connections := []*sharedmodel.Connection{} srv.data.Preload("Services").Preload("Services.Service").Preload("Services.Subscriptions").Find(&connections) c.JSON(http.StatusOK, connections) } func (srv *UIService) GetRegistrations(c *gin.Context) { registrations := []*sharedmodel.Registration{} srv.data.Where("status = ?", sharedmodel.RegistrationStatusPending).Find(®istrations) c.JSON(http.StatusOK, registrations) } func NewUIServer(addr string) *UIService { cert := loadCert() srv := &UIService{srv: &http.Server{ Addr: addr, Handler: gin.Default(), }, clientCert: *cert} return srv }