Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Commit

Permalink
submit error repots
Browse files Browse the repository at this point in the history
  • Loading branch information
dreske committed Sep 28, 2021
1 parent c23d43d commit 9d539aa
Show file tree
Hide file tree
Showing 24 changed files with 580 additions and 33 deletions.
19 changes: 19 additions & 0 deletions resources/db/migration/V1.2.0.1__create_reports.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
create table bug_reports
(
uuid varchar(36) not null primary key,
created timestamptz not null,
operator_uuid varchar(36) not null,
email varchar not null,
center_uuid varchar not null,
center_name varchar not null,
center_address varchar not null,
subject text not null,
message text
);

alter table operators
add email varchar,
add bug_reports_receiver varchar;

alter table centers
add email varchar;
22 changes: 22 additions & 0 deletions resources/db/migration/V1.2.0.2__add_system_settings.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
create table system_settings
(
config_key varchar not null primary key,
config_value text
);

INSERT INTO public.system_settings (config_key, config_value) VALUES ('reports.email.default', '[email protected]');
INSERT INTO public.system_settings (config_key, config_value) VALUES ('reports.email.subject', 'Meldungen zur Ihren Teststellen');
INSERT INTO public.system_settings (config_key, config_value) VALUES ('reports.email.template', 'Guten Tag,<br>
<br>
für Ihre Teststellen wurden folgende Fehler gemeldet.<br>
<br>
{{range $center, $reports := .Centers}}Meldungen für die Teststelle {{(index $reports 0).CenterName}} ({{(index $reports 0).CenterAddress}})<br>
<ul>
{{range $reportUUID, $report := $reports}}
<li>{{$report.Subject}} {{if $report.Message}}(Hinweis: {{$report.Message}}){{end}} (Gemeldet am {{$report.Created}}){{end}}</li>
</ul>
<br>
{{end}}
<br>
Viele Grüße<br>
Ihr Schnelltestportal.de Team');
27 changes: 20 additions & 7 deletions src/api/centers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ import (
"com.t-systems-mms.cwa/repositories"
"com.t-systems-mms.cwa/services"
"encoding/csv"
"encoding/json"
"github.com/go-chi/chi"
"github.com/go-chi/jwtauth"
"github.com/go-playground/validator"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/sirupsen/logrus"
"io"
"net/http"
"strconv"
"strings"
Expand Down Expand Up @@ -55,21 +54,27 @@ type Centers struct {
geocoder geocoding.Geocoder
operatorsService services.Operators
centersRepository repositories.Centers
bugReportsService services.BugReports
validate *validator.Validate
}

func NewCentersAPI(centersService services.Centers, centersRepository repositories.Centers,
bugReportsService services.BugReports,
operatorsService services.Operators, geocoder geocoding.Geocoder, auth *jwtauth.JWTAuth) *Centers {
centers := &Centers{
Router: chi.NewRouter(),
centersService: centersService,
centersRepository: centersRepository,
operatorsService: operatorsService,
geocoder: geocoder,
bugReportsService: bugReportsService,
validate: validator.New(),
}

// public endpoints
centers.Get("/", api.Handle(centers.FindCenters))
centers.Get("/bounds", api.Handle(centers.Geocode))
centers.Post("/{uuid}/report", api.Handle(centers.createBugReport))

centers.Group(func(r chi.Router) {
r.Use(jwtauth.Verifier(auth))
Expand Down Expand Up @@ -226,11 +231,7 @@ func (c *Centers) AdminGetCentersCSV(w http.ResponseWriter, r *http.Request) {

func (c *Centers) ImportCenters(_ http.ResponseWriter, r *http.Request) (interface{}, error) {
var importData model.ImportCenterRequest
buffer, err := io.ReadAll(r.Body)
if err != nil {
return nil, err
}
if err := json.Unmarshal(buffer, &importData); err != nil {
if err := api.ParseRequestBody(r, c.validate, &importData); err != nil {
return nil, err
}

Expand Down Expand Up @@ -276,6 +277,18 @@ func (c *Centers) deleteCenterByReference(_ http.ResponseWriter, r *http.Request
return nil, c.centersRepository.Delete(r.Context(), center)
}

// createBugReport creates a bug report for the specified center
func (c *Centers) createBugReport(_ http.ResponseWriter, r *http.Request) (interface{}, error) {
uuid := chi.URLParam(r, "uuid")
var request model.CreateBugReportRequestDTO
if err := api.ParseRequestBody(r, c.validate, &request); err != nil {
return nil, err
}

_, err := c.bugReportsService.CreateBugReport(r.Context(), uuid, request.Subject, request.Message)
return nil, err
}

func (c *Centers) DeleteCenter(_ http.ResponseWriter, r *http.Request) (interface{}, error) {
centerUUID := chi.URLParam(r, "uuid")
logrus.WithField("uuid", centerUUID).Trace("DeleteCenter")
Expand Down
6 changes: 6 additions & 0 deletions src/api/model/bugreport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package model

type CreateBugReportRequestDTO struct {
Subject string `json:"subject" validate:"required,max=160"`
Message *string `json:"message" validate:"omitempty,max=160"`
}
12 changes: 8 additions & 4 deletions src/api/model/centers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type FindCentersResult struct {
}

type ImportCenterRequest struct {
Centers []EditCenterDTO `json:"centers"`
Centers []EditCenterDTO `json:"centers" validate:"dive"`
DeleteAll bool `json:"deleteAll"`
}

Expand All @@ -30,6 +30,7 @@ type ImportCenterResult struct {
type CenterSummaryDTO struct {
UUID string `json:"uuid"`
Name string `json:"name"`
Email *string `json:"email"`
Website *string `json:"website"`
Coordinates *CoordinatesDTO `json:"coordinates"`
Logo *string `json:"logo"`
Expand Down Expand Up @@ -58,6 +59,7 @@ func (CenterSummaryDTO) MapFromDomain(center *domain.Center) *CenterSummaryDTO {
return &CenterSummaryDTO{
UUID: center.UUID,
Name: center.Name,
Email: center.Email,
Website: center.Website,
Coordinates: CoordinatesDTO{}.MapFromModel(&center.Coordinates),
Logo: getCenterLogo(center),
Expand Down Expand Up @@ -121,12 +123,13 @@ func MapToCenterDTOs(centers []domain.Center) []CenterDTO {
type EditCenterDTO struct {
UserReference *string `json:"userReference"`
Name string `json:"name" validate:"required"`
Email *string `json:"email" validate:"omitempty,email"`
Website *string `json:"website"`
Address string `json:"address" validate:"required"`
OpeningHours []string `json:"openingHours"`
OpeningHours []string `json:"openingHours" validate:"dive,max=64"`
AddressNote *string `json:"addressNote"`
Appointment *string `json:"appointment"`
TestKinds []string `json:"testKinds"`
Appointment *string `json:"appointment" validate:"omitempty,oneof=Required NotRequired Possible"`
TestKinds []string `json:"testKinds" validate:"dive,oneof=Antigen PCR Vaccination Antibody"`
DCC *bool `json:"dcc"`
EnterDate *string `json:"enterDate"`
LeaveDate *string `json:"leaveDate"`
Expand Down Expand Up @@ -160,6 +163,7 @@ func (c EditCenterDTO) MapToDomain() domain.Center {
DCC: c.DCC,
EnterDate: enterDate,
LeaveDate: leaveDate,
Email: c.Email,
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/api/model/operators.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type OperatorDTO struct {
UUID string `json:"uuid"`
OperatorNumber *string `json:"operatorNumber"`
Name string `json:"name"`
Email *string `json:"email"`
Logo *string `json:"logo"`
MarkerIcon *string `json:"markerIcon"`
}
Expand Down Expand Up @@ -33,5 +34,6 @@ func MapToOperatorDTO(operator *domain.Operator) *OperatorDTO {
Name: operator.Name,
Logo: logo,
MarkerIcon: markerIcon,
Email: operator.Email,
}
}
31 changes: 31 additions & 0 deletions src/cmd/backend/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"com.t-systems-mms.cwa/external/geocoding"
"com.t-systems-mms.cwa/services"
"errors"
"fmt"
"github.com/hashicorp/vault/api"
Expand All @@ -17,6 +18,8 @@ type Config struct {
Database DatabaseConfig
Google geocoding.GoogleGeocoderConfig
Authentication AuthenticationConfig
BugReports services.BugReportConfig
Email services.EmailConfig
}

type DatabaseConfig struct {
Expand Down Expand Up @@ -105,6 +108,34 @@ func LoadConfig() error {
appConfig.Database.IdlePoolSize = 10
}

// E-Mail
if err := readStringSecret(logicalClient, backend+"/data/email", "smtp-host",
&appConfig.Email.SmtpHost); err != nil {
return err
}
if err := readIntSecret(logicalClient, backend+"/data/email", "smtp-port",
&appConfig.Email.SmtpPort); err != nil {
return err
}
if err := readStringSecret(logicalClient, backend+"/data/email", "smtp-user",
&appConfig.Email.SmtpUser); err != nil {
return err
}
if err := readStringSecret(logicalClient, backend+"/data/email", "smtp-password",
&appConfig.Email.SmtpPassword); err != nil {
return err
}
if err := readStringSecret(logicalClient, backend+"/data/email", "from",
&appConfig.Email.From); err != nil {
return err
}

// Bug reports
if err := readIntSecret(logicalClient, backend+"/data/reports", "interval",
&appConfig.BugReports.Interval); err != nil {
appConfig.BugReports.Interval = 24 * 60
}

// Authentication
if err := readStringSecret(logicalClient, backend+"/data/authentication", "jwks-url",
&appConfig.Authentication.JwksUrl); err != nil {
Expand Down
12 changes: 11 additions & 1 deletion src/cmd/backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,19 @@ func main() {
sqlDB.SetMaxOpenConns(appConfig.Database.MaxOpenConns)
sqlDB.SetConnMaxLifetime(time.Duration(appConfig.Database.ConnMaxLifetime) * time.Minute)

settingsRepository := repositories.NewSystemSettingsRepository(db)

centersRepository := repositories.NewCentersRepository(db)
operatorsRepository := repositories.NewOperatorsRepository(db)
operatorsService := services.NewOperatorsService(operatorsRepository)
centersService := services.NewCentersService(centersRepository, operatorsRepository, operatorsService, geocoder)

mailService := services.NewMailService(appConfig.Email)

bugReportsRepository := repositories.NewBugReportsRepository(db)
bugReportsService := services.NewBugReportsService(appConfig.BugReports,
mailService, centersRepository, bugReportsRepository, settingsRepository)

// configure authentication
jwksSource := jwks.NewWebSource(appConfig.Authentication.JwksUrl)
jwksClient := jwks.NewDefaultClient(jwksSource, time.Hour, 12*time.Hour)
Expand All @@ -88,7 +96,7 @@ func main() {
router := chi.NewRouter()
router.Use(middleware.DefaultLogger)
router.Handle("/metrics", initMetricsHandler(centersRepository, operatorsRepository))
router.Mount("/api/centers", api.NewCentersAPI(centersService, centersRepository, operatorsService, geocoder, tokenAuth))
router.Mount("/api/centers", api.NewCentersAPI(centersService, centersRepository, bugReportsService, operatorsService, geocoder, tokenAuth))
router.Mount("/api/operators", api.NewOperatorsAPI(operatorsRepository, operatorsService, tokenAuth))

server := &http.Server{
Expand All @@ -109,6 +117,8 @@ func main() {
serverWaitHandle.Done()
}()

go bugReportsService.PublishScheduler()

signals := make(chan os.Signal, 1)
signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT)
<-signals
Expand Down
2 changes: 1 addition & 1 deletion src/core/api/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func createValidationErrorResponse(errors validator.ValidationErrors) Validation
for _, fieldError := range errors {
fields = append(fields, ValidationFieldError{
Field: fieldError.Field(),
Validation: fieldError.Tag(),
Validation: fieldError.Tag() + "=" + fieldError.Param(),
})
}
return ValidationErrorResponse{
Expand Down
17 changes: 17 additions & 0 deletions src/core/api/requesthandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/go-playground/validator"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
"io"
"net/http"
"time"
)
Expand Down Expand Up @@ -78,3 +79,19 @@ func WriteResponse(writer http.ResponseWriter, code int, body interface{}) {
}
}
}

// ParseRequestBody parses the request body, unmarshals the json into target and validates it
func ParseRequestBody(r *http.Request, validate *validator.Validate, target interface{}) error {
if data, err := io.ReadAll(r.Body); err == nil {
if err := json.Unmarshal(data, target); err == nil {
if vErr := validate.Struct(target); vErr != nil {
return vErr
}
} else {
return err
}
} else {
return err
}
return nil
}
21 changes: 21 additions & 0 deletions src/domain/bugreports.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package domain

import "time"

const (
ReportReceiverCenter = "center"
ReportReceiverOperator = "operator"
)

type BugReport struct {
UUID string `gorm:"primaryKey"`
Created time.Time
Email string
OperatorUUID string
Operator Operator
CenterUUID string
CenterName string
CenterAddress string
Subject string
Message *string
}
1 change: 1 addition & 0 deletions src/domain/centers.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ type Center struct {
Ranking float64
Zip *string
Region *string
Email *string `validate:"omitempty,email"`
}

type CenterWithDistance struct {
Expand Down
14 changes: 8 additions & 6 deletions src/domain/operator.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package domain

type Operator struct {
UUID string `gorm:"primaryKey"`
Subject *string
OperatorNumber *string
Name string
Logo *string
MarkerIcon *string
UUID string `gorm:"primaryKey"`
Subject *string
OperatorNumber *string
Name string
Logo *string
MarkerIcon *string
Email *string
BugReportsReceiver *string
}
6 changes: 6 additions & 0 deletions src/domain/systemsettings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package domain

type SystemSetting struct {
ConfigKey string
ConfigValue *string
}
1 change: 1 addition & 0 deletions src/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50
github.com/xhit/go-simple-mail/v2 v2.10.0 // indirect
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
golang.org/x/text v0.3.6 // indirect
googlemaps.github.io/maps v1.3.2
Expand Down
4 changes: 4 additions & 0 deletions src/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,10 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50 h1:uxE3GYdXIOfhMv3unJKETJEhw78gvzuQqRX/rVirc2A=
github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=
github.com/xhit/go-simple-mail v2.2.2+incompatible h1:Hm2VGfLqiQJ/NnC8SYsrPOPyVYIlvP2kmnotP4RIV74=
github.com/xhit/go-simple-mail v2.2.2+incompatible/go.mod h1:I8Ctg6vIJZ+Sv7k/22M6oeu/tbFumDY0uxBuuLbtU7Y=
github.com/xhit/go-simple-mail/v2 v2.10.0 h1:nib6RaJ4qVh5HD9UE9QJqnUZyWp3upv+Z6CFxaMj0V8=
github.com/xhit/go-simple-mail/v2 v2.10.0/go.mod h1:kA1XbQfCI4JxQ9ccSN6VFyIEkkugOm7YiPkA5hKiQn4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
Expand Down
Loading

0 comments on commit 9d539aa

Please sign in to comment.