From bb150f700f7219d4a5657d983837cc9cd43e5b39 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Fri, 14 Jun 2024 14:21:14 +0200 Subject: [PATCH 01/18] fix:#00 fixed old rproxy config for prod --- reverseproxy.conf | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/reverseproxy.conf b/reverseproxy.conf index c01c32c..301d969 100644 --- a/reverseproxy.conf +++ b/reverseproxy.conf @@ -125,7 +125,8 @@ http { proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s; - limit_req zone=$limit_zone burst=10 nodelay; + limit_req zone=feed burst=10 nodelay; + limit_req zone=createFeed burst=10 nodelay; limit_req_status 429; } @@ -147,12 +148,8 @@ http { proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s; - - # Apply rate limiting - if ($request_method = POST) { - limit_req zone=createFeed burst=10 nodelay; - } limit_req zone=feed burst=10 nodelay; + limit_req zone=createFeed burst=10 nodelay; limit_req_status 429; } @@ -188,7 +185,8 @@ http { proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s; - limit_req zone=$limit_zone burst=10 nodelay; + limit_req zone=feed burst=10 nodelay; + limit_req zone=createFeed burst=10 nodelay; limit_req_status 429; } From 8548a537ec5cf881f9b9e433aed62d8eac40e0a9 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Sun, 16 Jun 2024 02:54:50 +0200 Subject: [PATCH 02/18] feat:#36 added protobuf for golang microservices --- .gitlab-ci.yml | 1 - docker-compose.yml | 8 +- services/Makefile | 16 + services/data-manager/Dockerfile | 4 +- services/data-manager/go.mod | 93 ----- services/data-manager/go.sum | 385 ------------------ services/data-manager/main.go | 4 +- .../data-manager/service/addCalDavRoutes.go | 4 +- services/data-manager/service/addRoute.go | 14 +- services/data-manager/service/addSchedule.go | 12 +- .../service/course/courseFunctions.go | 2 +- services/data-manager/service/db/dbEvents.go | 2 +- .../data-manager/service/db/dbEvents_test.go | 2 +- services/data-manager/service/db/dbFeeds.go | 2 +- services/data-manager/service/db/dbGroups.go | 2 +- services/data-manager/service/db/dbRooms.go | 4 +- .../service/events/courseService.go | 4 +- .../service/events/eventService.go | 8 +- .../service/events/eventService_test.go | 2 +- .../service/feed/feedFunctions.go | 6 +- .../service/feed/feedFunctions_test.go | 4 +- .../service/fetch/sport/sportFetcher.go | 8 +- .../fetch/v1/fetchSeminarEventService.go | 8 +- .../fetch/v1/fetchSeminarEventService_test.go | 2 +- .../fetch/v1/fetchSeminarGroupService.go | 8 +- .../fetch/v1/fetchSeminarGroupService_test.go | 2 +- .../service/fetch/v2/eventParser.go | 6 +- .../data-manager/service/fetch/v2/fetcher.go | 12 +- .../service/fetch/v2/fetcher_test.go | 2 +- .../service/fetch/v2/htmlParsingFunctions.go | 4 +- .../service/functions/semester.go | 2 +- .../service/functions/semester_test.go | 2 +- services/data-manager/service/ical/ical.go | 4 +- .../service/ical/icalFileGeneration.go | 8 +- .../service/ical/icalFileGeneration_test.go | 4 +- .../service/names/userDefinedNameTemplates.go | 2 +- .../names/userDefinedNameTemplates_test.go | 2 +- .../data-manager/service/room/roomService.go | 6 +- .../service/room/roomService_test.go | 2 +- services/{ical => }/go.mod | 30 +- services/ical/Dockerfile | 20 +- services/ical/go.sum | 384 ----------------- services/ical/main.go | 2 +- .../ical/service/connector/feedConnector.go | 4 +- .../ical/service/connector/restHandler.go | 2 +- services/ical/service/functions/semester.go | 2 +- .../ical/service/functions/semester_test.go | 2 +- services/ical/service/functions/time/parse.go | 2 +- services/ical/service/ical/ical.go | 4 +- .../ical/service/ical/icalFileGeneration.go | 8 +- .../service/ical/icalFileGeneration_test.go | 4 +- .../service/names/userDefinedNameTemplates.go | 2 +- .../names/userDefinedNameTemplates_test.go | 2 +- services/ical/service/routes.go | 4 +- services/protobuf/modules.proto | 41 ++ 55 files changed, 186 insertions(+), 990 deletions(-) create mode 100644 services/Makefile delete mode 100644 services/data-manager/go.mod delete mode 100644 services/data-manager/go.sum rename services/{ical => }/go.mod (86%) delete mode 100644 services/ical/go.sum create mode 100644 services/protobuf/modules.proto diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3f0822b..87f07e3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,6 @@ stages: - build - test - sonarqube-check - - sonarqube-vulnerability-report - oci-build - deploy - deploy-dev # New stage for development deployment diff --git a/docker-compose.yml b/docker-compose.yml index c6a28f6..eef364e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,8 +17,8 @@ services: htwkalender-data-manager: build: - dockerfile: Dockerfile - context: services/data-manager + dockerfile: ./data-manager/Dockerfile + context: ./services target: dev # prod command: "--http=0.0.0.0:8090 --dir=/htwkalender-data-manager/data/pb_data" #ports: @@ -29,8 +29,8 @@ services: htwkalender-ical: build: - dockerfile: Dockerfile - context: services/ical + dockerfile: ./ical/Dockerfile + context: ./services target: dev # prod diff --git a/services/Makefile b/services/Makefile new file mode 100644 index 0000000..526dddd --- /dev/null +++ b/services/Makefile @@ -0,0 +1,16 @@ +run-data-manager: + @go run data-manager/main.go serve + +run-ical: + @go run ical/main.go + +build-ical: + @go build ical/main.go + +gen: + @protoc \ + --proto_path=protobuf "protobuf/modules.proto" \ + --go_out=common/genproto/modules \ + --go_opt=paths=source_relative \ + --go-grpc_out=common/genproto/modules \ + --go-grpc_opt=paths=source_relative \ No newline at end of file diff --git a/services/data-manager/Dockerfile b/services/data-manager/Dockerfile index 35dd5c8..408494a 100644 --- a/services/data-manager/Dockerfile +++ b/services/data-manager/Dockerfile @@ -53,8 +53,8 @@ FROM golang:1.21.6 AS dev WORKDIR /htwkalender-data-manager # Copy go mod and sum files -COPY go.mod go.sum ./ -RUN go mod download +# COPY ../go.mod ../go.sum ./ +# RUN go mod download # Copy the source from the current directory to the Working Directory inside the container COPY *.go ./ diff --git a/services/data-manager/go.mod b/services/data-manager/go.mod deleted file mode 100644 index 7a92cc2..0000000 --- a/services/data-manager/go.mod +++ /dev/null @@ -1,93 +0,0 @@ -module htwkalender - -go 1.21 - -require ( - github.com/PuerkitoBio/goquery v1.8.1 - github.com/google/uuid v1.5.0 - github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0 - github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 - github.com/pocketbase/dbx v1.10.1 - github.com/pocketbase/pocketbase v0.20.5 - golang.org/x/net v0.20.0 -) - -require ( - github.com/AlecAivazis/survey/v2 v2.3.7 // indirect - github.com/andybalholm/cascadia v1.3.2 // indirect - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.49.20 // indirect - github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.26.3 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect - github.com/aws/smithy-go v1.19.0 // indirect - github.com/disintegration/imaging v1.6.2 // indirect - github.com/domodwyer/mailyak/v3 v3.6.2 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/fatih/color v1.16.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/ganigeorgiev/fexpr v0.4.0 // indirect - github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/wire v0.5.0 // indirect - github.com/googleapis/gax-go/v2 v2.12.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.19 // indirect - github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - go.opencensus.io v0.24.0 // indirect - gocloud.dev v0.36.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/image v0.14.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.16.0 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/api v0.153.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.32.0 // indirect - lukechampine.com/uint128 v1.3.0 // indirect - modernc.org/cc/v3 v3.41.0 // indirect - modernc.org/ccgo/v3 v3.16.15 // indirect - modernc.org/libc v1.37.0 // indirect - modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.7.2 // indirect - modernc.org/opt v0.1.3 // indirect - modernc.org/sqlite v1.27.0 // indirect - modernc.org/strutil v1.2.0 // indirect - modernc.org/token v1.1.0 // indirect -) diff --git a/services/data-manager/go.sum b/services/data-manager/go.sum deleted file mode 100644 index ad5fe1f..0000000 --- a/services/data-manager/go.sum +++ /dev/null @@ -1,385 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= -cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= -cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= -cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= -cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= -cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= -github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= -github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= -github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= -github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= -github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= -github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= -github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.49.20 h1:VgEUq2/ZbUkLbqPyDcxrirfXB+PgiZUUF5XbsgWe2S0= -github.com/aws/aws-sdk-go v1.49.20/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= -github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo= -github.com/aws/aws-sdk-go-v2/config v1.26.3 h1:dKuc2jdp10y13dEEvPqWxqLoc0vF3Z9FC45MvuQSxOA= -github.com/aws/aws-sdk-go-v2/config v1.26.3/go.mod h1:Bxgi+DeeswYofcYO0XyGClwlrq3DZEXli0kLf4hkGA0= -github.com/aws/aws-sdk-go-v2/credentials v1.16.14 h1:mMDTwwYO9A0/JbOCOG7EOZHtYM+o7OfGWfu0toa23VE= -github.com/aws/aws-sdk-go-v2/credentials v1.16.14/go.mod h1:cniAUh3ErQPHtCQGPT5ouvSAQ0od8caTO9OOuufZOAE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11 h1:I6lAa3wBWfCz/cKkOpAcumsETRkFAl70sWi8ItcMEsM= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11/go.mod h1:be1NIO30kJA23ORBLqPo1LttEM6tPNSEcjkd1eKzNW0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 h1:5oE2WzJE56/mVveuDZPJESKlg/00AaS2pY2QZcnxg4M= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10/go.mod h1:FHbKWQtRBYUz4vO5WBWjzMD2by126ny5y/1EoaWoLfI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 h1:L0ai8WICYHozIKK+OtPzVJBugL7culcuM4E4JOpIEm8= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10/go.mod h1:byqfyxJBshFk0fF9YmK0M0ugIO8OWjzH2T3bPG4eGuA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 h1:KOxnQeWy5sXyS37fdKEvAsGHOr9fa/qvwxfJurR/BzE= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10/go.mod h1:jMx5INQFYFYB3lQD9W0D8Ohgq6Wnl7NYOJ2TQndbulI= -github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0 h1:PJTdBMsyvra6FtED7JZtDpQrIAflYDHFoZAu/sKYkwU= -github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0/go.mod h1:4qXHrG1Ne3VGIMZPCB8OjH/pLFO94sKABIusjh0KWPU= -github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 h1:dGrs+Q/WzhsiUKh82SfTVN66QzyulXuMDTV/G8ZxOac= -github.com/aws/aws-sdk-go-v2/service/sso v1.18.6/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 h1:Yf2MIo9x+0tyv76GljxzqA3WtC5mw7NmazD2chwjxE4= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= -github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= -github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= -github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= -github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= -github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= -github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= -github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8= -github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/ganigeorgiev/fexpr v0.4.0 h1:ojitI+VMNZX/odeNL1x3RzTTE8qAIVvnSSYPNAnQFDI= -github.com/ganigeorgiev/fexpr v0.4.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE= -github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= -github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE= -github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= -github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk= -github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg= -github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= -github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= -github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= -github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0 h1:p+k2RozdR141dIkAbOuZafkZjrcjT/YvwYYH7qCSG+c= -github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0/go.mod h1:YHaw6sOIeFRob8Y9q/blEAMfVcLpeE9+vdhrwyEMxoI= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 h1:FwuzbVh87iLiUQj1+uQUsuw9x5t9m5n5g7rG7o4svW4= -github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61/go.mod h1:paQfF1YtHe+GrGg5fOgjsjoCX/UKDr9bc1DoWpZfns8= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= -github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= -github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pocketbase/dbx v1.10.1 h1:cw+vsyfCJD8YObOVeqb93YErnlxwYMkNZ4rwN0G0AaA= -github.com/pocketbase/dbx v1.10.1/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs= -github.com/pocketbase/pocketbase v0.20.5 h1:unrGe6MG/D2AQDjjdcyh1WrbXI10wWe1gFcGdG/yaNU= -github.com/pocketbase/pocketbase v0.20.5/go.mod h1:uy7WOxXoICrwe8HlyR78vTvK0RdG5REkhDx4SvYi4FY= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -gocloud.dev v0.36.0 h1:q5zoXux4xkOZP473e1EZbG8Gq9f0vlg1VNH5Du/ybus= -gocloud.dev v0.36.0/go.mod h1:bLxah6JQVKBaIxzsr5BQLYB4IYdWHkMZdzCXlo6F0gg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= -golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= -google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f h1:Vn+VyHU5guc9KjB5KrjI2q0wCOWEOIh0OEsleqakHJg= -google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f/go.mod h1:nWSwAFPb+qfNJXsoeO3Io7zf4tMSfN8EA8RlDA04GhY= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 h1:DC7wcm+i+P1rN3Ff07vL+OndGg5OhNddHyTA+ocPqYE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= -lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= -modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= -modernc.org/ccgo/v3 v3.16.15 h1:KbDR3ZAVU+wiLyMESPtbtE/Add4elztFyfsWoNTgxS0= -modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI= -modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= -modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v1.37.0 h1:WerjebcsP6A7Jy+f2lCnHAkiSTLf7IaSftBYUtoswak= -modernc.org/libc v1.37.0/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= -modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.27.0 h1:MpKAHoyYB7xqcwnUwkuD+npwEa0fojF0B5QRbN+auJ8= -modernc.org/sqlite v1.27.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= -modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= -modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= -modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= -modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= -modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= diff --git a/services/data-manager/main.go b/services/data-manager/main.go index 8b78ba1..f8c0ece 100644 --- a/services/data-manager/main.go +++ b/services/data-manager/main.go @@ -19,8 +19,8 @@ package main import ( "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/plugins/migratecmd" - _ "htwkalender/migrations" - "htwkalender/service" + _ "htwkalender/data-manager/migrations" + "htwkalender/data-manager/service" "log/slog" "os" "strings" diff --git a/services/data-manager/service/addCalDavRoutes.go b/services/data-manager/service/addCalDavRoutes.go index 9aae82f..f487031 100644 --- a/services/data-manager/service/addCalDavRoutes.go +++ b/services/data-manager/service/addCalDavRoutes.go @@ -21,8 +21,8 @@ import ( "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/apis" "github.com/pocketbase/pocketbase/core" - "htwkalender/service/db" - "htwkalender/service/ical" + "htwkalender/data-manager/service/db" + "htwkalender/data-manager/service/ical" "io" "log/slog" "net/http" diff --git a/services/data-manager/service/addRoute.go b/services/data-manager/service/addRoute.go index 0f131bf..8dadd40 100644 --- a/services/data-manager/service/addRoute.go +++ b/services/data-manager/service/addRoute.go @@ -17,13 +17,13 @@ package service import ( - "htwkalender/service/course" - "htwkalender/service/events" - "htwkalender/service/fetch/sport" - v1 "htwkalender/service/fetch/v1" - v2 "htwkalender/service/fetch/v2" - "htwkalender/service/functions/time" - "htwkalender/service/room" + "htwkalender/data-manager/service/course" + "htwkalender/data-manager/service/events" + "htwkalender/data-manager/service/fetch/sport" + v1 "htwkalender/data-manager/service/fetch/v1" + v2 "htwkalender/data-manager/service/fetch/v2" + "htwkalender/data-manager/service/functions/time" + "htwkalender/data-manager/service/room" "log/slog" "net/http" diff --git a/services/data-manager/service/addSchedule.go b/services/data-manager/service/addSchedule.go index 9d2b901..c24f2e1 100644 --- a/services/data-manager/service/addSchedule.go +++ b/services/data-manager/service/addSchedule.go @@ -20,12 +20,12 @@ import ( "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/cron" - "htwkalender/service/course" - "htwkalender/service/feed" - "htwkalender/service/fetch/sport" - v1 "htwkalender/service/fetch/v1" - v2 "htwkalender/service/fetch/v2" - "htwkalender/service/functions/time" + "htwkalender/data-manager/service/course" + "htwkalender/data-manager/service/feed" + "htwkalender/data-manager/service/fetch/sport" + v1 "htwkalender/data-manager/service/fetch/v1" + v2 "htwkalender/data-manager/service/fetch/v2" + "htwkalender/data-manager/service/functions/time" "log/slog" "strconv" ) diff --git a/services/data-manager/service/course/courseFunctions.go b/services/data-manager/service/course/courseFunctions.go index d51ad00..0612d97 100644 --- a/services/data-manager/service/course/courseFunctions.go +++ b/services/data-manager/service/course/courseFunctions.go @@ -18,7 +18,7 @@ package course import ( "github.com/pocketbase/pocketbase" - "htwkalender/service/events" + "htwkalender/data-manager/service/events" "log/slog" ) diff --git a/services/data-manager/service/db/dbEvents.go b/services/data-manager/service/db/dbEvents.go index 8c971f4..2296de8 100644 --- a/services/data-manager/service/db/dbEvents.go +++ b/services/data-manager/service/db/dbEvents.go @@ -20,7 +20,7 @@ import ( "fmt" "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/tools/types" - "htwkalender/model" + "htwkalender/data-manager/model" "log/slog" "time" diff --git a/services/data-manager/service/db/dbEvents_test.go b/services/data-manager/service/db/dbEvents_test.go index 20505a6..14542e0 100644 --- a/services/data-manager/service/db/dbEvents_test.go +++ b/services/data-manager/service/db/dbEvents_test.go @@ -18,7 +18,7 @@ package db import ( "github.com/pocketbase/dbx" - "htwkalender/model" + "htwkalender/data-manager/model" "reflect" "testing" ) diff --git a/services/data-manager/service/db/dbFeeds.go b/services/data-manager/service/db/dbFeeds.go index 49ea58b..1ad6ad3 100644 --- a/services/data-manager/service/db/dbFeeds.go +++ b/services/data-manager/service/db/dbFeeds.go @@ -22,7 +22,7 @@ import ( "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/models" - "htwkalender/model" + "htwkalender/data-manager/model" "time" ) diff --git a/services/data-manager/service/db/dbGroups.go b/services/data-manager/service/db/dbGroups.go index 1e5d02c..f4776c3 100644 --- a/services/data-manager/service/db/dbGroups.go +++ b/services/data-manager/service/db/dbGroups.go @@ -20,7 +20,7 @@ import ( "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/models" - "htwkalender/model" + "htwkalender/data-manager/model" "log/slog" ) diff --git a/services/data-manager/service/db/dbRooms.go b/services/data-manager/service/db/dbRooms.go index f89bbdc..45564c1 100644 --- a/services/data-manager/service/db/dbRooms.go +++ b/services/data-manager/service/db/dbRooms.go @@ -17,8 +17,8 @@ package db import ( - "htwkalender/model" - "htwkalender/service/functions" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/functions" "strings" "time" diff --git a/services/data-manager/service/events/courseService.go b/services/data-manager/service/events/courseService.go index 308e049..389a428 100644 --- a/services/data-manager/service/events/courseService.go +++ b/services/data-manager/service/events/courseService.go @@ -18,8 +18,8 @@ package events import ( "github.com/pocketbase/pocketbase" - "htwkalender/service/db" - "htwkalender/service/functions" + "htwkalender/data-manager/service/db" + "htwkalender/data-manager/service/functions" ) func GetAllCourses(app *pocketbase.PocketBase) []string { diff --git a/services/data-manager/service/events/eventService.go b/services/data-manager/service/events/eventService.go index c9184c5..383640c 100644 --- a/services/data-manager/service/events/eventService.go +++ b/services/data-manager/service/events/eventService.go @@ -18,10 +18,10 @@ package events import ( "github.com/pocketbase/pocketbase" - "htwkalender/model" - "htwkalender/service/db" - "htwkalender/service/fetch/v1" - "htwkalender/service/functions" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/db" + "htwkalender/data-manager/service/fetch/v1" + "htwkalender/data-manager/service/functions" "log/slog" "strconv" ) diff --git a/services/data-manager/service/events/eventService_test.go b/services/data-manager/service/events/eventService_test.go index 6c5c23e..e4f7b68 100644 --- a/services/data-manager/service/events/eventService_test.go +++ b/services/data-manager/service/events/eventService_test.go @@ -1,7 +1,7 @@ package events import ( - "htwkalender/model" + "htwkalender/data-manager/model" "testing" ) diff --git a/services/data-manager/service/feed/feedFunctions.go b/services/data-manager/service/feed/feedFunctions.go index 894f322..6c3da36 100644 --- a/services/data-manager/service/feed/feedFunctions.go +++ b/services/data-manager/service/feed/feedFunctions.go @@ -20,9 +20,9 @@ import ( "database/sql" "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/daos" - "htwkalender/model" - database "htwkalender/service/db" - localTime "htwkalender/service/functions/time" + "htwkalender/data-manager/model" + database "htwkalender/data-manager/service/db" + localTime "htwkalender/data-manager/service/functions/time" "log/slog" "strings" ) diff --git a/services/data-manager/service/feed/feedFunctions_test.go b/services/data-manager/service/feed/feedFunctions_test.go index e35f3f8..53286ba 100644 --- a/services/data-manager/service/feed/feedFunctions_test.go +++ b/services/data-manager/service/feed/feedFunctions_test.go @@ -19,8 +19,8 @@ package feed import ( "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/tests" - "htwkalender/model" - mockTime "htwkalender/service/functions/time" + "htwkalender/data-manager/model" + mockTime "htwkalender/data-manager/service/functions/time" "reflect" "testing" "time" diff --git a/services/data-manager/service/fetch/sport/sportFetcher.go b/services/data-manager/service/fetch/sport/sportFetcher.go index 4cb619c..93ecdfc 100644 --- a/services/data-manager/service/fetch/sport/sportFetcher.go +++ b/services/data-manager/service/fetch/sport/sportFetcher.go @@ -21,10 +21,10 @@ import ( "github.com/google/uuid" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/tools/types" - "htwkalender/model" - "htwkalender/service/db" - "htwkalender/service/functions" - clock "htwkalender/service/functions/time" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/db" + "htwkalender/data-manager/service/functions" + clock "htwkalender/data-manager/service/functions/time" "io" "log/slog" "net/http" diff --git a/services/data-manager/service/fetch/v1/fetchSeminarEventService.go b/services/data-manager/service/fetch/v1/fetchSeminarEventService.go index ca02906..4f3679d 100644 --- a/services/data-manager/service/fetch/v1/fetchSeminarEventService.go +++ b/services/data-manager/service/fetch/v1/fetchSeminarEventService.go @@ -21,10 +21,10 @@ import ( "github.com/google/uuid" "github.com/pocketbase/pocketbase/tools/types" "golang.org/x/net/html" - "htwkalender/model" - "htwkalender/service/date" - "htwkalender/service/fetch" - "htwkalender/service/functions" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/date" + "htwkalender/data-manager/service/fetch" + "htwkalender/data-manager/service/functions" "log/slog" "regexp" "strconv" diff --git a/services/data-manager/service/fetch/v1/fetchSeminarEventService_test.go b/services/data-manager/service/fetch/v1/fetchSeminarEventService_test.go index a5c103b..10b55cd 100644 --- a/services/data-manager/service/fetch/v1/fetchSeminarEventService_test.go +++ b/services/data-manager/service/fetch/v1/fetchSeminarEventService_test.go @@ -19,7 +19,7 @@ package v1 import ( "fmt" "github.com/pocketbase/pocketbase/tools/types" - "htwkalender/model" + "htwkalender/data-manager/model" "reflect" "testing" "time" diff --git a/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go b/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go index 9e909e5..32cfff0 100644 --- a/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go +++ b/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go @@ -21,10 +21,10 @@ import ( "fmt" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/models" - "htwkalender/model" - "htwkalender/service/db" - "htwkalender/service/functions" - "htwkalender/service/functions/time" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/db" + "htwkalender/data-manager/service/functions" + "htwkalender/data-manager/service/functions/time" "io" "log/slog" "net/http" diff --git a/services/data-manager/service/fetch/v1/fetchSeminarGroupService_test.go b/services/data-manager/service/fetch/v1/fetchSeminarGroupService_test.go index 16cdee0..6c2cfbe 100644 --- a/services/data-manager/service/fetch/v1/fetchSeminarGroupService_test.go +++ b/services/data-manager/service/fetch/v1/fetchSeminarGroupService_test.go @@ -17,7 +17,7 @@ package v1 import ( - "htwkalender/model" + "htwkalender/data-manager/model" "testing" ) diff --git a/services/data-manager/service/fetch/v2/eventParser.go b/services/data-manager/service/fetch/v2/eventParser.go index 94eafe2..3482bd7 100644 --- a/services/data-manager/service/fetch/v2/eventParser.go +++ b/services/data-manager/service/fetch/v2/eventParser.go @@ -19,9 +19,9 @@ package v2 import ( "github.com/pocketbase/pocketbase/tools/types" "golang.org/x/net/html" - "htwkalender/model" - "htwkalender/service/date" - "htwkalender/service/functions" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/date" + "htwkalender/data-manager/service/functions" "strings" ) diff --git a/services/data-manager/service/fetch/v2/fetcher.go b/services/data-manager/service/fetch/v2/fetcher.go index 35cc75a..f8af754 100644 --- a/services/data-manager/service/fetch/v2/fetcher.go +++ b/services/data-manager/service/fetch/v2/fetcher.go @@ -22,12 +22,12 @@ import ( "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/daos" "golang.org/x/net/html" - "htwkalender/model" - "htwkalender/service/db" - "htwkalender/service/fetch" - v1 "htwkalender/service/fetch/v1" - "htwkalender/service/functions" - localTime "htwkalender/service/functions/time" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/db" + "htwkalender/data-manager/service/fetch" + v1 "htwkalender/data-manager/service/fetch/v1" + "htwkalender/data-manager/service/functions" + localTime "htwkalender/data-manager/service/functions/time" "log/slog" "strings" ) diff --git a/services/data-manager/service/fetch/v2/fetcher_test.go b/services/data-manager/service/fetch/v2/fetcher_test.go index 9b2dec1..0a3e2ad 100644 --- a/services/data-manager/service/fetch/v2/fetcher_test.go +++ b/services/data-manager/service/fetch/v2/fetcher_test.go @@ -17,7 +17,7 @@ package v2 import ( - "htwkalender/model" + "htwkalender/data-manager/model" "reflect" "testing" ) diff --git a/services/data-manager/service/fetch/v2/htmlParsingFunctions.go b/services/data-manager/service/fetch/v2/htmlParsingFunctions.go index fc240b5..4f09a57 100644 --- a/services/data-manager/service/fetch/v2/htmlParsingFunctions.go +++ b/services/data-manager/service/fetch/v2/htmlParsingFunctions.go @@ -19,8 +19,8 @@ package v2 import ( "github.com/pocketbase/pocketbase/tools/types" "golang.org/x/net/html" - "htwkalender/model" - "htwkalender/service/date" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/date" "regexp" "strconv" "strings" diff --git a/services/data-manager/service/functions/semester.go b/services/data-manager/service/functions/semester.go index 2ac4ea6..c95191a 100644 --- a/services/data-manager/service/functions/semester.go +++ b/services/data-manager/service/functions/semester.go @@ -17,7 +17,7 @@ package functions import ( - localTime "htwkalender/service/functions/time" + localTime "htwkalender/data-manager/service/functions/time" "time" ) diff --git a/services/data-manager/service/functions/semester_test.go b/services/data-manager/service/functions/semester_test.go index eb71898..35a8f9c 100644 --- a/services/data-manager/service/functions/semester_test.go +++ b/services/data-manager/service/functions/semester_test.go @@ -1,7 +1,7 @@ package functions import ( - mockTime "htwkalender/service/functions/time" + mockTime "htwkalender/data-manager/service/functions/time" "reflect" "testing" "time" diff --git a/services/data-manager/service/ical/ical.go b/services/data-manager/service/ical/ical.go index ec604fc..9711f11 100644 --- a/services/data-manager/service/ical/ical.go +++ b/services/data-manager/service/ical/ical.go @@ -20,8 +20,8 @@ import ( "encoding/json" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/apis" - "htwkalender/model" - "htwkalender/service/db" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/db" ) func CreateIndividualFeed(requestBody []byte, app *pocketbase.PocketBase) (string, error) { diff --git a/services/data-manager/service/ical/icalFileGeneration.go b/services/data-manager/service/ical/icalFileGeneration.go index 31ba7d7..b2ee39b 100644 --- a/services/data-manager/service/ical/icalFileGeneration.go +++ b/services/data-manager/service/ical/icalFileGeneration.go @@ -17,10 +17,10 @@ package ical import ( - "htwkalender/model" - "htwkalender/service/functions" - clock "htwkalender/service/functions/time" - "htwkalender/service/names" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/functions" + clock "htwkalender/data-manager/service/functions/time" + "htwkalender/data-manager/service/names" "time" "github.com/jordic/goics" diff --git a/services/data-manager/service/ical/icalFileGeneration_test.go b/services/data-manager/service/ical/icalFileGeneration_test.go index f48f413..383a387 100644 --- a/services/data-manager/service/ical/icalFileGeneration_test.go +++ b/services/data-manager/service/ical/icalFileGeneration_test.go @@ -18,8 +18,8 @@ package ical import ( "github.com/jordic/goics" - "htwkalender/model" - mockTime "htwkalender/service/functions/time" + "htwkalender/data-manager/model" + mockTime "htwkalender/data-manager/service/functions/time" "reflect" "testing" "time" diff --git a/services/data-manager/service/names/userDefinedNameTemplates.go b/services/data-manager/service/names/userDefinedNameTemplates.go index 3033623..11425bb 100644 --- a/services/data-manager/service/names/userDefinedNameTemplates.go +++ b/services/data-manager/service/names/userDefinedNameTemplates.go @@ -17,7 +17,7 @@ package names import ( - "htwkalender/model" + "htwkalender/data-manager/model" "regexp" ) diff --git a/services/data-manager/service/names/userDefinedNameTemplates_test.go b/services/data-manager/service/names/userDefinedNameTemplates_test.go index 9fe9c7d..a1b88c3 100644 --- a/services/data-manager/service/names/userDefinedNameTemplates_test.go +++ b/services/data-manager/service/names/userDefinedNameTemplates_test.go @@ -17,7 +17,7 @@ package names import ( - "htwkalender/model" + "htwkalender/data-manager/model" "testing" ) diff --git a/services/data-manager/service/room/roomService.go b/services/data-manager/service/room/roomService.go index fdf9ab9..151746d 100644 --- a/services/data-manager/service/room/roomService.go +++ b/services/data-manager/service/room/roomService.go @@ -18,9 +18,9 @@ package room import ( "github.com/pocketbase/pocketbase" - "htwkalender/model" - "htwkalender/service/db" - "htwkalender/service/functions" + "htwkalender/data-manager/model" + "htwkalender/data-manager/service/db" + "htwkalender/data-manager/service/functions" "time" ) diff --git a/services/data-manager/service/room/roomService_test.go b/services/data-manager/service/room/roomService_test.go index 4f0f91f..b4bf733 100644 --- a/services/data-manager/service/room/roomService_test.go +++ b/services/data-manager/service/room/roomService_test.go @@ -18,7 +18,7 @@ package room import ( "github.com/pocketbase/pocketbase/tools/types" - "htwkalender/model" + "htwkalender/data-manager/model" "reflect" "testing" ) diff --git a/services/ical/go.mod b/services/go.mod similarity index 86% rename from services/ical/go.mod rename to services/go.mod index c087dbe..036f954 100644 --- a/services/ical/go.mod +++ b/services/go.mod @@ -1,16 +1,24 @@ -module htwkalender-ical +module htwkalender -go 1.21.6 +go 1.21 require ( + github.com/PuerkitoBio/goquery v1.9.2 github.com/gofiber/fiber/v3 v3.0.0-beta.2 + github.com/google/uuid v1.6.0 github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0 + github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 + github.com/pocketbase/dbx v1.10.1 github.com/pocketbase/pocketbase v0.22.12 + golang.org/x/net v0.26.0 + google.golang.org/grpc v1.63.2 + google.golang.org/protobuf v1.34.1 ) require ( github.com/AlecAivazis/survey/v2 v2.3.7 // indirect github.com/andybalholm/brotli v1.1.0 // indirect + github.com/andybalholm/cascadia v1.3.2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 // indirect @@ -42,44 +50,38 @@ require ( github.com/gofiber/utils/v2 v2.0.0-beta.4 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/uuid v1.6.0 // indirect github.com/googleapis/gax-go/v2 v2.12.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/klauspost/compress v1.17.8 // indirect - github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 // indirect + github.com/klauspost/compress v1.17.6 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/pocketbase/dbx v1.10.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.54.0 // indirect + github.com/valyala/fasthttp v1.52.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/tcplisten v1.0.0 // indirect go.opencensus.io v0.24.0 // indirect gocloud.dev v0.37.0 // indirect - golang.org/x/crypto v0.23.0 // indirect + golang.org/x/crypto v0.24.0 // indirect golang.org/x/image v0.16.0 // indirect - golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/term v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/api v0.180.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 // indirect - google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.34.1 // indirect modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect modernc.org/libc v1.50.5 // indirect modernc.org/mathutil v1.6.0 // indirect diff --git a/services/ical/Dockerfile b/services/ical/Dockerfile index 2bc4c3b..03e4a10 100644 --- a/services/ical/Dockerfile +++ b/services/ical/Dockerfile @@ -19,12 +19,14 @@ FROM golang:alpine AS build WORKDIR /app +RUN apk add --no-cache --update go gcc g++ # Copy the source from the current directory to the Working Directory inside the container -COPY . ./ -# download needed modules -RUN apk add --no-cache --update go gcc g++ && \ - go mod download && \ - CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-ical +COPY go.mod go.sum ./ +RUN go mod download + +COPY ical/*.go ./ical/ +COPY ical/. ./ical +RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-ical ical/main.go # production stage FROM alpine:latest AS prod @@ -57,14 +59,14 @@ COPY go.mod go.sum ./ RUN go mod download # Copy the source from the current directory to the Working Directory inside the container -COPY *.go ./ -COPY . . +COPY ical/*.go ./ical/ +COPY ical/. ./ical # Build the Go app -RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-ical +RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-ical ical/main.go # Expose port 8091 to the outside world EXPOSE 8091 # Entry point -ENTRYPOINT ["./htwkalender-ical"] \ No newline at end of file +ENTRYPOINT ["./main"] \ No newline at end of file diff --git a/services/ical/go.sum b/services/ical/go.sum deleted file mode 100644 index e4d76bd..0000000 --- a/services/ical/go.sum +++ /dev/null @@ -1,384 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw= -cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= -cloud.google.com/go/auth v0.4.1 h1:Z7YNIhlWRtrnKlZke7z3GMqzvuYzdc2z98F9D1NV5Hg= -cloud.google.com/go/auth v0.4.1/go.mod h1:QVBuVEKpCn4Zp58hzRGvL0tjRGU0YqdRTdCHM1IHnro= -cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= -cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= -cloud.google.com/go/compute v1.25.0 h1:H1/4SqSUhjPFE7L5ddzHOfY2bCAvjwNRZPNl6Ni5oYU= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/storage v1.39.1 h1:MvraqHKhogCOTXTlct/9C3K3+Uy2jBmFYb3/Sp6dVtY= -cloud.google.com/go/storage v1.39.1/go.mod h1:xK6xZmxZmo+fyP7+DEF6FhNc24/JAe95OLyOHCXFH1o= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= -github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.51.11 h1:El5VypsMIz7sFwAAj/j06JX9UGs4KAbAIEaZ57bNY4s= -github.com/aws/aws-sdk-go v1.51.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= -github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2/go.mod h1:lPprDr1e6cJdyYeGXnRaJoP4Md+cDBvi2eOj00BlGmg= -github.com/aws/aws-sdk-go-v2/config v1.27.13 h1:WbKW8hOzrWoOA/+35S5okqO/2Ap8hkkFUzoW8Hzq24A= -github.com/aws/aws-sdk-go-v2/config v1.27.13/go.mod h1:XLiyiTMnguytjRER7u5RIkhIqS8Nyz41SwAWb4xEjxs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.13 h1:XDCJDzk/u5cN7Aple7D/MiAhx1Rjo/0nueJ0La8mRuE= -github.com/aws/aws-sdk-go-v2/credentials v1.17.13/go.mod h1:FMNcjQrmuBYvOTZDtOLCIu0esmxjF7RuA/89iSXWzQI= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 h1:FVJ0r5XTHSmIHJV6KuDmdYhEpvlHpiSd38RQWhut5J4= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1/go.mod h1:zusuAeqezXzAB24LGuzuekqMAEgWkVYukBec3kr3jUg= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.17 h1:9b1Os1s11mF5qTIKLgSsyPG810di2+ySSLIIt9bwe9I= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.17/go.mod h1:9Wp7tDOMhv0+sb/FTRAkbHNQ7abYDnoJRzm5AAtCnTc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.5 h1:81KE7vaZzrl7yHBYHVEzYB8sypz11NMOZ40YlWvPxsU= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.5/go.mod h1:LIt2rg7Mcgn09Ygbdh/RdIm0rQ+3BNkbP1gyVMFtRK0= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.7 h1:ZMeFZ5yk+Ek+jNr1+uwCd2tG89t6oTS5yVWpa6yy2es= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.7/go.mod h1:mxV05U+4JiHqIpGqqYXOHLPKUC6bDXC44bsUhNjOEwY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.5 h1:f9RyWNtS8oH7cZlbn+/JNPpjUk5+5fLd5lM9M0i49Ys= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.5/go.mod h1:h5CoMZV2VF297/VLhRhO1WF+XYWOzXo+4HsObA4HjBQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.53.2 h1:rq2hglTQM3yHZvOPVMtNvLS5x6hijx7JvRDgKiTNDGQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.53.2/go.mod h1:qmdkIIAC+GCLASF7R2whgNrJADz0QZPX+Seiw/i4S3o= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.6 h1:o5cTaeunSpfXiLTIBx5xo2enQmiChtu1IBbzXnfU9Hs= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.6/go.mod h1:qGzynb/msuZIE8I75DVRCUXw3o3ZyBmUvMwQ2t/BrGM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0 h1:Qe0r0lVURDDeBQJ4yP+BOrJkvkiCo/3FH/t+wY11dmw= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0/go.mod h1:mUYPBhaF2lGiukDEjJX2BLRRKTmoUSitGDUgM4tRxak= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.7 h1:et3Ta53gotFR4ERLXXHIHl/Uuk1qYpP5uU7cvNql8ns= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.7/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw= -github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= -github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= -github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= -github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= -github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8= -github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/ganigeorgiev/fexpr v0.4.0 h1:ojitI+VMNZX/odeNL1x3RzTTE8qAIVvnSSYPNAnQFDI= -github.com/ganigeorgiev/fexpr v0.4.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= -github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4= -github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/gofiber/fiber/v3 v3.0.0-beta.2 h1:mVVgt8PTaHGup3NGl/+7U7nEoZaXJ5OComV4E+HpAao= -github.com/gofiber/fiber/v3 v3.0.0-beta.2/go.mod h1:w7sdfTY0okjZ1oVH6rSOGvuACUIt0By1iK0HKUb3uqM= -github.com/gofiber/utils/v2 v2.0.0-beta.4 h1:1gjbVFFwVwUb9arPcqiB6iEjHBwo7cHsyS41NeIW3co= -github.com/gofiber/utils/v2 v2.0.0-beta.4/go.mod h1:sdRsPU1FXX6YiDGGxd+q2aPJRMzpsxdzCXo9dz+xtOY= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= -github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= -github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= -github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0 h1:p+k2RozdR141dIkAbOuZafkZjrcjT/YvwYYH7qCSG+c= -github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0/go.mod h1:YHaw6sOIeFRob8Y9q/blEAMfVcLpeE9+vdhrwyEMxoI= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 h1:FwuzbVh87iLiUQj1+uQUsuw9x5t9m5n5g7rG7o4svW4= -github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61/go.mod h1:paQfF1YtHe+GrGg5fOgjsjoCX/UKDr9bc1DoWpZfns8= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= -github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= -github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pocketbase/dbx v1.10.1 h1:cw+vsyfCJD8YObOVeqb93YErnlxwYMkNZ4rwN0G0AaA= -github.com/pocketbase/dbx v1.10.1/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs= -github.com/pocketbase/pocketbase v0.22.12 h1:2wWcs2yoyA3OkbW9cxFShemzchOh3eHFr1e8QvLy5is= -github.com/pocketbase/pocketbase v0.22.12/go.mod h1:yY/3IGi1tUbcI6yGVFspAyKi/IDHCntdYk4IAP32UF0= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.54.0 h1:cCL+ZZR3z3HPLMVfEYVUMtJqVaui0+gu7Lx63unHwS0= -github.com/valyala/fasthttp v1.54.0/go.mod h1:6dt4/8olwq9QARP/TDuPmWyWcl4byhpvTJ4AAtcz+QM= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -gocloud.dev v0.37.0 h1:XF1rN6R0qZI/9DYjN16Uy0durAmSlf58DHOcb28GPro= -gocloud.dev v0.37.0/go.mod h1:7/O4kqdInCNsc6LqgmuFnS0GRew4XNNYWpA44yQnwco= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw= -golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/api v0.180.0 h1:M2D87Yo0rGBPWpo1orwfCLehUUL6E7/TYe5gvMQWDh4= -google.golang.org/api v0.180.0/go.mod h1:51AiyoEg1MJPSZ9zvklA8VnRILPXxn1iVen9v25XHAE= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 h1:ImUcDPHjTrAqNhlOkSocDLfG9rrNHH7w7uoKWPaWZ8s= -google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7/go.mod h1:/3XmxOjePkvmKrHuBy4zNFw7IzxJXtAgdpXi8Ll990U= -google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU= -google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 h1:umK/Ey0QEzurTNlsV3R+MfxHAb78HCEX/IkuR+zH4WQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434/go.mod h1:I7Y+G38R2bu5j1aLzfFmQfTcU/WnFuqDwLZAbvKTKpM= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -modernc.org/cc/v4 v4.21.0 h1:D/gLKtcztomvWbsbvBKo3leKQv+86f+DdqEZBBXhnag= -modernc.org/cc/v4 v4.21.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.17.3 h1:t2CQci84jnxKw3GGnHvjGKjiNZeZqyQx/023spkk4hU= -modernc.org/ccgo/v4 v4.17.3/go.mod h1:1FCbAtWYJoKuc+AviS+dH+vGNtYmFJqBeRWjmnDWsIg= -modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= -modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= -modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8= -modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.50.5 h1:ZzeUd0dIc/sUtoPTCYIrgypkuzoGzNu6kbEWj2VuEmk= -modernc.org/libc v1.50.5/go.mod h1:rhzrUx5oePTSTIzBgM0mTftwWHK8tiT9aNFUt1mldl0= -modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= -modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= -modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.29.9 h1:9RhNMklxJs+1596GNuAX+O/6040bvOwacTxuFcRuQow= -modernc.org/sqlite v1.29.9/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA= -modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= -modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/services/ical/main.go b/services/ical/main.go index 4865e7c..d8ad1e9 100644 --- a/services/ical/main.go +++ b/services/ical/main.go @@ -20,7 +20,7 @@ import ( "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/log" "github.com/gofiber/fiber/v3/middleware/logger" - "htwkalender-ical/service" + "htwkalender/ical/service" ) // main function for the ical service diff --git a/services/ical/service/connector/feedConnector.go b/services/ical/service/connector/feedConnector.go index 7c98663..acd3abd 100644 --- a/services/ical/service/connector/feedConnector.go +++ b/services/ical/service/connector/feedConnector.go @@ -3,7 +3,7 @@ package connector import ( "encoding/json" "errors" - "htwkalender-ical/model" + "htwkalender/ical/model" "log/slog" ) @@ -51,8 +51,6 @@ func DeleteFeedRecord(token string) error { func GetModuleWithEvents(module model.FeedModule) (model.Module, error) { var modules model.Module - // /api/module?uuid= - response, err := RequestApi("/api/module?uuid=" + module.UUID) if err != nil { return model.Module{}, err diff --git a/services/ical/service/connector/restHandler.go b/services/ical/service/connector/restHandler.go index 7fc3381..89d1385 100644 --- a/services/ical/service/connector/restHandler.go +++ b/services/ical/service/connector/restHandler.go @@ -2,7 +2,7 @@ package connector import ( "github.com/gofiber/fiber/v3/client" - "htwkalender-ical/model" + "htwkalender/ical/model" "time" ) diff --git a/services/ical/service/functions/semester.go b/services/ical/service/functions/semester.go index 9cf7006..001fe73 100644 --- a/services/ical/service/functions/semester.go +++ b/services/ical/service/functions/semester.go @@ -17,7 +17,7 @@ package functions import ( - localTime "htwkalender-ical/service/functions/time" + localTime "htwkalender/ical/service/functions/time" "time" ) diff --git a/services/ical/service/functions/semester_test.go b/services/ical/service/functions/semester_test.go index 5a5f96c..0f46f11 100644 --- a/services/ical/service/functions/semester_test.go +++ b/services/ical/service/functions/semester_test.go @@ -1,7 +1,7 @@ package functions import ( - mockTime "htwkalender-ical/service/functions/time" + mockTime "htwkalender/ical/service/functions/time" "reflect" "testing" "time" diff --git a/services/ical/service/functions/time/parse.go b/services/ical/service/functions/time/parse.go index 97a4f22..dc3ff4a 100644 --- a/services/ical/service/functions/time/parse.go +++ b/services/ical/service/functions/time/parse.go @@ -17,7 +17,7 @@ package time import ( - "htwkalender-ical/model" + "htwkalender/ical/model" "time" ) diff --git a/services/ical/service/ical/ical.go b/services/ical/service/ical/ical.go index 05ae05d..0ffd6ab 100644 --- a/services/ical/service/ical/ical.go +++ b/services/ical/service/ical/ical.go @@ -3,8 +3,8 @@ package ical import ( "bytes" "github.com/jordic/goics" - "htwkalender-ical/model" - "htwkalender-ical/service/connector" + "htwkalender/ical/model" + "htwkalender/ical/service/connector" "log/slog" "time" ) diff --git a/services/ical/service/ical/icalFileGeneration.go b/services/ical/service/ical/icalFileGeneration.go index 57eb4a3..9af0c60 100644 --- a/services/ical/service/ical/icalFileGeneration.go +++ b/services/ical/service/ical/icalFileGeneration.go @@ -17,10 +17,10 @@ package ical import ( - "htwkalender-ical/model" - "htwkalender-ical/service/functions" - clock "htwkalender-ical/service/functions/time" - "htwkalender-ical/service/names" + "htwkalender/ical/model" + "htwkalender/ical/service/functions" + clock "htwkalender/ical/service/functions/time" + "htwkalender/ical/service/names" "time" "github.com/jordic/goics" diff --git a/services/ical/service/ical/icalFileGeneration_test.go b/services/ical/service/ical/icalFileGeneration_test.go index c1a92f0..f85702f 100644 --- a/services/ical/service/ical/icalFileGeneration_test.go +++ b/services/ical/service/ical/icalFileGeneration_test.go @@ -18,8 +18,8 @@ package ical import ( "github.com/jordic/goics" - "htwkalender-ical/model" - mockTime "htwkalender-ical/service/functions/time" + "htwkalender/ical/model" + mockTime "htwkalender/ical/service/functions/time" "reflect" "testing" "time" diff --git a/services/ical/service/names/userDefinedNameTemplates.go b/services/ical/service/names/userDefinedNameTemplates.go index 59250ff..ee05e6e 100644 --- a/services/ical/service/names/userDefinedNameTemplates.go +++ b/services/ical/service/names/userDefinedNameTemplates.go @@ -17,7 +17,7 @@ package names import ( - "htwkalender-ical/model" + "htwkalender/ical/model" "regexp" ) diff --git a/services/ical/service/names/userDefinedNameTemplates_test.go b/services/ical/service/names/userDefinedNameTemplates_test.go index bb5ee2b..8915551 100644 --- a/services/ical/service/names/userDefinedNameTemplates_test.go +++ b/services/ical/service/names/userDefinedNameTemplates_test.go @@ -17,7 +17,7 @@ package names import ( - "htwkalender-ical/model" + "htwkalender/ical/model" "testing" ) diff --git a/services/ical/service/routes.go b/services/ical/service/routes.go index ee59f0f..5bd1eed 100644 --- a/services/ical/service/routes.go +++ b/services/ical/service/routes.go @@ -4,8 +4,8 @@ import ( "encoding/json" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/log" - "htwkalender-ical/model" - "htwkalender-ical/service/ical" + "htwkalender/ical/model" + "htwkalender/ical/service/ical" "log/slog" "net/http" ) diff --git a/services/protobuf/modules.proto b/services/protobuf/modules.proto new file mode 100644 index 0000000..cfeba31 --- /dev/null +++ b/services/protobuf/modules.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +option go_package = "htwkalender/common/modules"; + +service ModuleService { + rpc GetModule(GetModuleRequest) returns (GetModuleResponse) {} +} + +message Event { + string uuid = 1; + string day = 2; + string week = 3; + string start = 4; + string end = 5; + string name = 6; + string eventType = 7; + string compulsory = 8; + string prof = 9; + string rooms = 10; + string notes = 11; + string bookedAt = 12; + string course = 13; + string semester = 14; +} + +message Module { + string uuid = 1; + string name = 2; + string prof = 3; + string course = 4; + string semester = 5; + repeated Event events = 6; +} + +message GetModuleRequest { + string uuid = 1; +} + +message GetModuleResponse { + repeated Module module = 1; +} \ No newline at end of file From fad85f2884b6ce31c2313d9bb88df081098dff8d Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Mon, 17 Jun 2024 00:59:33 +0200 Subject: [PATCH 03/18] feat:#36 added protobuf communication for modules --- .../common/genproto/modules/modules.pb.go | 509 ++++++++++++++++++ .../genproto/modules/modules_grpc.pb.go | 105 ++++ services/data-manager/Dockerfile | 30 +- services/data-manager/main.go | 5 + services/data-manager/service/grpc/mapper.go | 25 + services/data-manager/service/grpc/server.go | 69 +++ services/go.sum | 399 ++++++++++++++ services/ical/Dockerfile | 6 +- services/ical/main.go | 19 +- services/ical/model/appModel.go | 13 + services/ical/model/icalModel.go | 15 +- .../ical/service/connector/feedConnector.go | 16 +- .../ical/service/connector/grpc/client.go | 21 + .../ical/service/connector/grpc/modules.go | 54 ++ .../ical/service/connector/restHandler.go | 8 +- services/ical/service/ical/ical.go | 21 +- services/ical/service/routes.go | 28 +- services/protobuf/modules.proto | 2 +- 18 files changed, 1286 insertions(+), 59 deletions(-) create mode 100644 services/common/genproto/modules/modules.pb.go create mode 100644 services/common/genproto/modules/modules_grpc.pb.go create mode 100644 services/data-manager/service/grpc/mapper.go create mode 100644 services/data-manager/service/grpc/server.go create mode 100644 services/go.sum create mode 100644 services/ical/model/appModel.go create mode 100644 services/ical/service/connector/grpc/client.go create mode 100644 services/ical/service/connector/grpc/modules.go diff --git a/services/common/genproto/modules/modules.pb.go b/services/common/genproto/modules/modules.pb.go new file mode 100644 index 0000000..cc88a8b --- /dev/null +++ b/services/common/genproto/modules/modules.pb.go @@ -0,0 +1,509 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v5.27.1 +// source: modules.proto + +package modules + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Event struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` + Day string `protobuf:"bytes,2,opt,name=day,proto3" json:"day,omitempty"` + Week string `protobuf:"bytes,3,opt,name=week,proto3" json:"week,omitempty"` + Start string `protobuf:"bytes,4,opt,name=start,proto3" json:"start,omitempty"` + End string `protobuf:"bytes,5,opt,name=end,proto3" json:"end,omitempty"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + EventType string `protobuf:"bytes,7,opt,name=eventType,proto3" json:"eventType,omitempty"` + Compulsory string `protobuf:"bytes,8,opt,name=compulsory,proto3" json:"compulsory,omitempty"` + Prof string `protobuf:"bytes,9,opt,name=prof,proto3" json:"prof,omitempty"` + Rooms string `protobuf:"bytes,10,opt,name=rooms,proto3" json:"rooms,omitempty"` + Notes string `protobuf:"bytes,11,opt,name=notes,proto3" json:"notes,omitempty"` + BookedAt string `protobuf:"bytes,12,opt,name=bookedAt,proto3" json:"bookedAt,omitempty"` + Course string `protobuf:"bytes,13,opt,name=course,proto3" json:"course,omitempty"` + Semester string `protobuf:"bytes,14,opt,name=semester,proto3" json:"semester,omitempty"` +} + +func (x *Event) Reset() { + *x = Event{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Event) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event) ProtoMessage() {} + +func (x *Event) ProtoReflect() protoreflect.Message { + mi := &file_modules_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Event.ProtoReflect.Descriptor instead. +func (*Event) Descriptor() ([]byte, []int) { + return file_modules_proto_rawDescGZIP(), []int{0} +} + +func (x *Event) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +func (x *Event) GetDay() string { + if x != nil { + return x.Day + } + return "" +} + +func (x *Event) GetWeek() string { + if x != nil { + return x.Week + } + return "" +} + +func (x *Event) GetStart() string { + if x != nil { + return x.Start + } + return "" +} + +func (x *Event) GetEnd() string { + if x != nil { + return x.End + } + return "" +} + +func (x *Event) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Event) GetEventType() string { + if x != nil { + return x.EventType + } + return "" +} + +func (x *Event) GetCompulsory() string { + if x != nil { + return x.Compulsory + } + return "" +} + +func (x *Event) GetProf() string { + if x != nil { + return x.Prof + } + return "" +} + +func (x *Event) GetRooms() string { + if x != nil { + return x.Rooms + } + return "" +} + +func (x *Event) GetNotes() string { + if x != nil { + return x.Notes + } + return "" +} + +func (x *Event) GetBookedAt() string { + if x != nil { + return x.BookedAt + } + return "" +} + +func (x *Event) GetCourse() string { + if x != nil { + return x.Course + } + return "" +} + +func (x *Event) GetSemester() string { + if x != nil { + return x.Semester + } + return "" +} + +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Prof string `protobuf:"bytes,3,opt,name=prof,proto3" json:"prof,omitempty"` + Course string `protobuf:"bytes,4,opt,name=course,proto3" json:"course,omitempty"` + Semester string `protobuf:"bytes,5,opt,name=semester,proto3" json:"semester,omitempty"` + Events []*Event `protobuf:"bytes,6,rep,name=events,proto3" json:"events,omitempty"` +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +func (x *Module) ProtoReflect() protoreflect.Message { + mi := &file_modules_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_modules_proto_rawDescGZIP(), []int{1} +} + +func (x *Module) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +func (x *Module) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Module) GetProf() string { + if x != nil { + return x.Prof + } + return "" +} + +func (x *Module) GetCourse() string { + if x != nil { + return x.Course + } + return "" +} + +func (x *Module) GetSemester() string { + if x != nil { + return x.Semester + } + return "" +} + +func (x *Module) GetEvents() []*Event { + if x != nil { + return x.Events + } + return nil +} + +type GetModuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` +} + +func (x *GetModuleRequest) Reset() { + *x = GetModuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetModuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModuleRequest) ProtoMessage() {} + +func (x *GetModuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_modules_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModuleRequest.ProtoReflect.Descriptor instead. +func (*GetModuleRequest) Descriptor() ([]byte, []int) { + return file_modules_proto_rawDescGZIP(), []int{2} +} + +func (x *GetModuleRequest) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +type GetModuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Module *Module `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` +} + +func (x *GetModuleResponse) Reset() { + *x = GetModuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetModuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModuleResponse) ProtoMessage() {} + +func (x *GetModuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_modules_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModuleResponse.ProtoReflect.Descriptor instead. +func (*GetModuleResponse) Descriptor() ([]byte, []int) { + return file_modules_proto_rawDescGZIP(), []int{3} +} + +func (x *GetModuleResponse) GetModule() *Module { + if x != nil { + return x.Module + } + return nil +} + +var File_modules_proto protoreflect.FileDescriptor + +var file_modules_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xcb, 0x02, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, + 0x03, 0x64, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x61, 0x79, 0x12, + 0x12, 0x0a, 0x04, 0x77, 0x65, 0x65, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x77, + 0x65, 0x65, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x6c, 0x73, 0x6f, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x6c, 0x73, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x72, 0x6f, 0x66, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x72, 0x6f, + 0x66, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x72, 0x6f, 0x6f, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x0a, + 0x08, 0x62, 0x6f, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x62, 0x6f, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x75, + 0x72, 0x73, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x72, 0x22, 0x98, 0x01, + 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x72, 0x6f, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x70, 0x72, 0x6f, 0x66, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x73, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x73, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x26, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, + 0x22, 0x34, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x32, 0x45, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x12, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1c, 0x5a, + 0x1a, 0x68, 0x74, 0x77, 0x6b, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_modules_proto_rawDescOnce sync.Once + file_modules_proto_rawDescData = file_modules_proto_rawDesc +) + +func file_modules_proto_rawDescGZIP() []byte { + file_modules_proto_rawDescOnce.Do(func() { + file_modules_proto_rawDescData = protoimpl.X.CompressGZIP(file_modules_proto_rawDescData) + }) + return file_modules_proto_rawDescData +} + +var file_modules_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_modules_proto_goTypes = []interface{}{ + (*Event)(nil), // 0: Event + (*Module)(nil), // 1: Module + (*GetModuleRequest)(nil), // 2: GetModuleRequest + (*GetModuleResponse)(nil), // 3: GetModuleResponse +} +var file_modules_proto_depIdxs = []int32{ + 0, // 0: Module.events:type_name -> Event + 1, // 1: GetModuleResponse.module:type_name -> Module + 2, // 2: ModuleService.GetModule:input_type -> GetModuleRequest + 3, // 3: ModuleService.GetModule:output_type -> GetModuleResponse + 3, // [3:4] is the sub-list for method output_type + 2, // [2:3] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_modules_proto_init() } +func file_modules_proto_init() { + if File_modules_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_modules_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Event); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Module); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetModuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetModuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_modules_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_modules_proto_goTypes, + DependencyIndexes: file_modules_proto_depIdxs, + MessageInfos: file_modules_proto_msgTypes, + }.Build() + File_modules_proto = out.File + file_modules_proto_rawDesc = nil + file_modules_proto_goTypes = nil + file_modules_proto_depIdxs = nil +} diff --git a/services/common/genproto/modules/modules_grpc.pb.go b/services/common/genproto/modules/modules_grpc.pb.go new file mode 100644 index 0000000..eafc547 --- /dev/null +++ b/services/common/genproto/modules/modules_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v5.27.1 +// source: modules.proto + +package modules + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ModuleServiceClient is the client API for ModuleService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ModuleServiceClient interface { + GetModule(ctx context.Context, in *GetModuleRequest, opts ...grpc.CallOption) (*GetModuleResponse, error) +} + +type moduleServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewModuleServiceClient(cc grpc.ClientConnInterface) ModuleServiceClient { + return &moduleServiceClient{cc} +} + +func (c *moduleServiceClient) GetModule(ctx context.Context, in *GetModuleRequest, opts ...grpc.CallOption) (*GetModuleResponse, error) { + out := new(GetModuleResponse) + err := c.cc.Invoke(ctx, "/ModuleService/GetModule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ModuleServiceServer is the server API for ModuleService service. +// All implementations must embed UnimplementedModuleServiceServer +// for forward compatibility +type ModuleServiceServer interface { + GetModule(context.Context, *GetModuleRequest) (*GetModuleResponse, error) + mustEmbedUnimplementedModuleServiceServer() +} + +// UnimplementedModuleServiceServer must be embedded to have forward compatible implementations. +type UnimplementedModuleServiceServer struct { +} + +func (UnimplementedModuleServiceServer) GetModule(context.Context, *GetModuleRequest) (*GetModuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetModule not implemented") +} +func (UnimplementedModuleServiceServer) mustEmbedUnimplementedModuleServiceServer() {} + +// UnsafeModuleServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ModuleServiceServer will +// result in compilation errors. +type UnsafeModuleServiceServer interface { + mustEmbedUnimplementedModuleServiceServer() +} + +func RegisterModuleServiceServer(s grpc.ServiceRegistrar, srv ModuleServiceServer) { + s.RegisterService(&ModuleService_ServiceDesc, srv) +} + +func _ModuleService_GetModule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetModuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ModuleServiceServer).GetModule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ModuleService/GetModule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ModuleServiceServer).GetModule(ctx, req.(*GetModuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ModuleService_ServiceDesc is the grpc.ServiceDesc for ModuleService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ModuleService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ModuleService", + HandlerType: (*ModuleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetModule", + Handler: _ModuleService_GetModule_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "modules.proto", +} diff --git a/services/data-manager/Dockerfile b/services/data-manager/Dockerfile index 408494a..7bb6a3f 100644 --- a/services/data-manager/Dockerfile +++ b/services/data-manager/Dockerfile @@ -19,12 +19,14 @@ FROM golang:alpine AS build WORKDIR /app +RUN apk add --no-cache --update go gcc g++ # Copy the source from the current directory to the Working Directory inside the container -COPY . ./ -# download needed modules -RUN apk add --no-cache --update go gcc g++ && \ - go mod download && \ - CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-data-manager +COPY go.mod go.sum ./ +RUN go mod download + +COPY data-manager/. ./data-manager +COPY common/. ./common +RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-data-manager data-manager/main.go # production stage FROM alpine:latest AS prod @@ -44,7 +46,7 @@ COPY --chown=$USER:$USER --from=build /htwkalender-data-manager ./ # Expose port 8090 to the outside world EXPOSE 8090 -ENTRYPOINT ["./htwkalender-data-manager", "serve"] +ENTRYPOINT ["./main", "serve"] FROM golang:1.21.6 AS dev @@ -53,18 +55,18 @@ FROM golang:1.21.6 AS dev WORKDIR /htwkalender-data-manager # Copy go mod and sum files -# COPY ../go.mod ../go.sum ./ -# RUN go mod download +COPY go.mod go.sum ./ +RUN go mod download # Copy the source from the current directory to the Working Directory inside the container -COPY *.go ./ -COPY . . +COPY data-manager/. ./data-manager +COPY common/. ./common # Build the Go app -RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-data-manager +RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-data-manager data-manager/main.go -# Expose port 8090 to the outside world -EXPOSE 8090 +# Expose port 8091 to the outside world +EXPOSE 8091 # Entry point -ENTRYPOINT ["./htwkalender-data-manager", "serve"] \ No newline at end of file +ENTRYPOINT ["./main", "serve"] \ No newline at end of file diff --git a/services/data-manager/main.go b/services/data-manager/main.go index f8c0ece..c49c157 100644 --- a/services/data-manager/main.go +++ b/services/data-manager/main.go @@ -21,6 +21,7 @@ import ( "github.com/pocketbase/pocketbase/plugins/migratecmd" _ "htwkalender/data-manager/migrations" "htwkalender/data-manager/service" + "htwkalender/data-manager/service/grpc" "log/slog" "os" "strings" @@ -32,6 +33,9 @@ func main() { // loosely check if it was executed using "go run" isGoRun := strings.HasPrefix(os.Args[0], os.TempDir()) + //start grpc server + go grpc.StartGRPCServer(app) + migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{ // enable auto creation of migration files when making collection changes in the Admin UI // (the isGoRun check is to enable it only during development) @@ -43,4 +47,5 @@ func main() { if err := app.Start(); err != nil { slog.Error("Failed to start app: ", "error", err) } + } diff --git a/services/data-manager/service/grpc/mapper.go b/services/data-manager/service/grpc/mapper.go new file mode 100644 index 0000000..b352d45 --- /dev/null +++ b/services/data-manager/service/grpc/mapper.go @@ -0,0 +1,25 @@ +package grpc + +import ( + pb "htwkalender/common/genproto/modules" + "htwkalender/data-manager/model" +) + +func eventToProto(event *model.Event) *pb.Event { + return &pb.Event{ + Uuid: event.UUID, + Day: event.Day, + Week: event.Week, + Start: event.Start.String(), + End: event.End.String(), + Name: event.Name, + EventType: event.EventType, + Compulsory: event.Compulsory, + Prof: event.Prof, + Rooms: event.Rooms, + Notes: event.Notes, + BookedAt: event.BookedAt, + Course: event.Course, + Semester: event.Semester, + } +} diff --git a/services/data-manager/service/grpc/server.go b/services/data-manager/service/grpc/server.go new file mode 100644 index 0000000..9ad33f9 --- /dev/null +++ b/services/data-manager/service/grpc/server.go @@ -0,0 +1,69 @@ +package grpc + +import ( + "context" + "github.com/pocketbase/pocketbase" + "htwkalender/data-manager/service/db" + "log" + "net" + + "google.golang.org/grpc" + pb "htwkalender/common/genproto/modules" +) + +type ModulesGrpcHandler struct { + app *pocketbase.PocketBase + pb.UnimplementedModuleServiceServer +} + +func (s *ModulesGrpcHandler) GetModule(ctx context.Context, in *pb.GetModuleRequest) (*pb.GetModuleResponse, error) { + + // get module from database by UUID + + module, err := db.FindModuleByUUID(s.app, in.Uuid) + if err != nil { + return nil, err + } + + events, err := db.FindAllEventsByModule(s.app, module) + if err != nil { + return nil, err + } + + //map module Events to proto struct Events + protoEvents := make([]*pb.Event, 0) + for _, event := range events { + protoEvents = append(protoEvents, eventToProto(&event)) + } + + //map module to proto struct + protoModule := &pb.Module{ + Uuid: module.UUID, + Name: module.Name, + Prof: module.Prof, + Course: module.Course, + Semester: module.Semester, + Events: protoEvents, + } + + // Implement your logic here to fetch module data based on the UUID + // Example response + return &pb.GetModuleResponse{ + Module: protoModule, + }, nil +} + +func StartGRPCServer(app *pocketbase.PocketBase) { + lis, err := net.Listen("tcp", ":50051") + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterModuleServiceServer(s, &ModulesGrpcHandler{ + app: app, + }) + log.Printf("server listening at %v", lis.Addr()) + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} diff --git a/services/go.sum b/services/go.sum new file mode 100644 index 0000000..407fba5 --- /dev/null +++ b/services/go.sum @@ -0,0 +1,399 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw= +cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= +cloud.google.com/go/auth v0.4.1 h1:Z7YNIhlWRtrnKlZke7z3GMqzvuYzdc2z98F9D1NV5Hg= +cloud.google.com/go/auth v0.4.1/go.mod h1:QVBuVEKpCn4Zp58hzRGvL0tjRGU0YqdRTdCHM1IHnro= +cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= +cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= +cloud.google.com/go/compute v1.25.0 h1:H1/4SqSUhjPFE7L5ddzHOfY2bCAvjwNRZPNl6Ni5oYU= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/storage v1.39.1 h1:MvraqHKhogCOTXTlct/9C3K3+Uy2jBmFYb3/Sp6dVtY= +cloud.google.com/go/storage v1.39.1/go.mod h1:xK6xZmxZmo+fyP7+DEF6FhNc24/JAe95OLyOHCXFH1o= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= +github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= +github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE= +github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= +github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.51.11 h1:El5VypsMIz7sFwAAj/j06JX9UGs4KAbAIEaZ57bNY4s= +github.com/aws/aws-sdk-go v1.51.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= +github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2/go.mod h1:lPprDr1e6cJdyYeGXnRaJoP4Md+cDBvi2eOj00BlGmg= +github.com/aws/aws-sdk-go-v2/config v1.27.13 h1:WbKW8hOzrWoOA/+35S5okqO/2Ap8hkkFUzoW8Hzq24A= +github.com/aws/aws-sdk-go-v2/config v1.27.13/go.mod h1:XLiyiTMnguytjRER7u5RIkhIqS8Nyz41SwAWb4xEjxs= +github.com/aws/aws-sdk-go-v2/credentials v1.17.13 h1:XDCJDzk/u5cN7Aple7D/MiAhx1Rjo/0nueJ0La8mRuE= +github.com/aws/aws-sdk-go-v2/credentials v1.17.13/go.mod h1:FMNcjQrmuBYvOTZDtOLCIu0esmxjF7RuA/89iSXWzQI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 h1:FVJ0r5XTHSmIHJV6KuDmdYhEpvlHpiSd38RQWhut5J4= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1/go.mod h1:zusuAeqezXzAB24LGuzuekqMAEgWkVYukBec3kr3jUg= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.17 h1:9b1Os1s11mF5qTIKLgSsyPG810di2+ySSLIIt9bwe9I= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.17/go.mod h1:9Wp7tDOMhv0+sb/FTRAkbHNQ7abYDnoJRzm5AAtCnTc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.5 h1:81KE7vaZzrl7yHBYHVEzYB8sypz11NMOZ40YlWvPxsU= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.5/go.mod h1:LIt2rg7Mcgn09Ygbdh/RdIm0rQ+3BNkbP1gyVMFtRK0= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.7 h1:ZMeFZ5yk+Ek+jNr1+uwCd2tG89t6oTS5yVWpa6yy2es= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.7/go.mod h1:mxV05U+4JiHqIpGqqYXOHLPKUC6bDXC44bsUhNjOEwY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.5 h1:f9RyWNtS8oH7cZlbn+/JNPpjUk5+5fLd5lM9M0i49Ys= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.5/go.mod h1:h5CoMZV2VF297/VLhRhO1WF+XYWOzXo+4HsObA4HjBQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.53.2 h1:rq2hglTQM3yHZvOPVMtNvLS5x6hijx7JvRDgKiTNDGQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.53.2/go.mod h1:qmdkIIAC+GCLASF7R2whgNrJADz0QZPX+Seiw/i4S3o= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.6 h1:o5cTaeunSpfXiLTIBx5xo2enQmiChtu1IBbzXnfU9Hs= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.6/go.mod h1:qGzynb/msuZIE8I75DVRCUXw3o3ZyBmUvMwQ2t/BrGM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0 h1:Qe0r0lVURDDeBQJ4yP+BOrJkvkiCo/3FH/t+wY11dmw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0/go.mod h1:mUYPBhaF2lGiukDEjJX2BLRRKTmoUSitGDUgM4tRxak= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.7 h1:et3Ta53gotFR4ERLXXHIHl/Uuk1qYpP5uU7cvNql8ns= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.7/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw= +github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= +github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= +github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8= +github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/ganigeorgiev/fexpr v0.4.0 h1:ojitI+VMNZX/odeNL1x3RzTTE8qAIVvnSSYPNAnQFDI= +github.com/ganigeorgiev/fexpr v0.4.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= +github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4= +github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gofiber/fiber/v3 v3.0.0-beta.2 h1:mVVgt8PTaHGup3NGl/+7U7nEoZaXJ5OComV4E+HpAao= +github.com/gofiber/fiber/v3 v3.0.0-beta.2/go.mod h1:w7sdfTY0okjZ1oVH6rSOGvuACUIt0By1iK0HKUb3uqM= +github.com/gofiber/utils/v2 v2.0.0-beta.4 h1:1gjbVFFwVwUb9arPcqiB6iEjHBwo7cHsyS41NeIW3co= +github.com/gofiber/utils/v2 v2.0.0-beta.4/go.mod h1:sdRsPU1FXX6YiDGGxd+q2aPJRMzpsxdzCXo9dz+xtOY= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= +github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= +github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0 h1:p+k2RozdR141dIkAbOuZafkZjrcjT/YvwYYH7qCSG+c= +github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0/go.mod h1:YHaw6sOIeFRob8Y9q/blEAMfVcLpeE9+vdhrwyEMxoI= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 h1:FwuzbVh87iLiUQj1+uQUsuw9x5t9m5n5g7rG7o4svW4= +github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61/go.mod h1:paQfF1YtHe+GrGg5fOgjsjoCX/UKDr9bc1DoWpZfns8= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pocketbase/dbx v1.10.1 h1:cw+vsyfCJD8YObOVeqb93YErnlxwYMkNZ4rwN0G0AaA= +github.com/pocketbase/dbx v1.10.1/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs= +github.com/pocketbase/pocketbase v0.22.12 h1:2wWcs2yoyA3OkbW9cxFShemzchOh3eHFr1e8QvLy5is= +github.com/pocketbase/pocketbase v0.22.12/go.mod h1:yY/3IGi1tUbcI6yGVFspAyKi/IDHCntdYk4IAP32UF0= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0= +github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +gocloud.dev v0.37.0 h1:XF1rN6R0qZI/9DYjN16Uy0durAmSlf58DHOcb28GPro= +gocloud.dev v0.37.0/go.mod h1:7/O4kqdInCNsc6LqgmuFnS0GRew4XNNYWpA44yQnwco= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw= +golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.180.0 h1:M2D87Yo0rGBPWpo1orwfCLehUUL6E7/TYe5gvMQWDh4= +google.golang.org/api v0.180.0/go.mod h1:51AiyoEg1MJPSZ9zvklA8VnRILPXxn1iVen9v25XHAE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 h1:ImUcDPHjTrAqNhlOkSocDLfG9rrNHH7w7uoKWPaWZ8s= +google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7/go.mod h1:/3XmxOjePkvmKrHuBy4zNFw7IzxJXtAgdpXi8Ll990U= +google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU= +google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 h1:umK/Ey0QEzurTNlsV3R+MfxHAb78HCEX/IkuR+zH4WQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434/go.mod h1:I7Y+G38R2bu5j1aLzfFmQfTcU/WnFuqDwLZAbvKTKpM= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +modernc.org/cc/v4 v4.21.0 h1:D/gLKtcztomvWbsbvBKo3leKQv+86f+DdqEZBBXhnag= +modernc.org/cc/v4 v4.21.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.17.3 h1:t2CQci84jnxKw3GGnHvjGKjiNZeZqyQx/023spkk4hU= +modernc.org/ccgo/v4 v4.17.3/go.mod h1:1FCbAtWYJoKuc+AviS+dH+vGNtYmFJqBeRWjmnDWsIg= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= +modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= +modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8= +modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.50.5 h1:ZzeUd0dIc/sUtoPTCYIrgypkuzoGzNu6kbEWj2VuEmk= +modernc.org/libc v1.50.5/go.mod h1:rhzrUx5oePTSTIzBgM0mTftwWHK8tiT9aNFUt1mldl0= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= +modernc.org/sqlite v1.29.9 h1:9RhNMklxJs+1596GNuAX+O/6040bvOwacTxuFcRuQow= +modernc.org/sqlite v1.29.9/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/services/ical/Dockerfile b/services/ical/Dockerfile index 03e4a10..d87835a 100644 --- a/services/ical/Dockerfile +++ b/services/ical/Dockerfile @@ -24,8 +24,8 @@ RUN apk add --no-cache --update go gcc g++ COPY go.mod go.sum ./ RUN go mod download -COPY ical/*.go ./ical/ COPY ical/. ./ical +COPY common/. ./common RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-ical ical/main.go # production stage @@ -46,7 +46,7 @@ COPY --chown=$USER:$USER --from=build /htwkalender-ical ./ # Expose port 8091 to the outside world EXPOSE 8091 -ENTRYPOINT ["./htwkalender-ical"] +ENTRYPOINT ["./main"] FROM golang:1.21.6 AS dev @@ -59,8 +59,8 @@ COPY go.mod go.sum ./ RUN go mod download # Copy the source from the current directory to the Working Directory inside the container -COPY ical/*.go ./ical/ COPY ical/. ./ical +COPY common/. ./common # Build the Go app RUN CGO_ENABLED=1 GOOS=linux go build -o /htwkalender-ical ical/main.go diff --git a/services/ical/main.go b/services/ical/main.go index d8ad1e9..b1a3138 100644 --- a/services/ical/main.go +++ b/services/ical/main.go @@ -20,18 +20,24 @@ import ( "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/log" "github.com/gofiber/fiber/v3/middleware/logger" + "htwkalender/ical/model" "htwkalender/ical/service" + "htwkalender/ical/service/connector/grpc" ) // main function for the ical service // uses rest api to get the data from the data-manager // exposes rest api endpoints with fiber to serve the data for clients func main() { + const host = "htwkalender-data-manager" + + grpcClient := grpc.ConnectGRPCServer(host) + defer grpc.CloseGRPCServer(grpcClient) // Initialize a new Fiber app webdavRequestMethods := []string{"PROPFIND", "MKCOL", "COPY", "MOVE"} - app := fiber.New(fiber.Config{ + fiberApp := fiber.New(fiber.Config{ CaseSensitive: true, StrictRouting: true, ServerHeader: "Fiber", @@ -39,10 +45,17 @@ func main() { RequestMethods: append(fiber.DefaultMethods[:], webdavRequestMethods...), }) - app.Use(logger.New()) + var app = model.AppType{ + GrpcClient: grpcClient, + Host: host, + Fiber: fiberApp, + DataManagerURL: "http://" + host + ":8090", + } + + fiberApp.Use(logger.New()) // Add routes to the app instance for the data-manager ical service service.AddFeedRoutes(app) - log.Fatal(app.Listen(":8091")) + log.Fatal(fiberApp.Listen(":8091")) } diff --git a/services/ical/model/appModel.go b/services/ical/model/appModel.go new file mode 100644 index 0000000..2238b09 --- /dev/null +++ b/services/ical/model/appModel.go @@ -0,0 +1,13 @@ +package model + +import ( + "github.com/gofiber/fiber/v3" + googleGRPC "google.golang.org/grpc" +) + +type AppType struct { + GrpcClient *googleGRPC.ClientConn + Host string + Fiber *fiber.App + DataManagerURL string +} diff --git a/services/ical/model/icalModel.go b/services/ical/model/icalModel.go index a8b09ed..cbd11bf 100644 --- a/services/ical/model/icalModel.go +++ b/services/ical/model/icalModel.go @@ -19,10 +19,14 @@ package model import ( "encoding/json" "fmt" + "log/slog" "strings" "time" ) +// DefaultDateLayout specifies the default app date strings layout. +const DefaultDateLayout = "2006-01-02 15:04:05.000Z" + // IcalModel local type for EmitICal function type IcalModel struct { Events Events @@ -73,10 +77,19 @@ func (jt *JSONTime) UnmarshalJSON(b []byte) error { if timeString == "null" || timeString == "" { return nil } - t, err := time.Parse("2006-01-02 15:04:05.000Z", timeString) + t, err := time.Parse(DefaultDateLayout, timeString) if err == nil { *jt = JSONTime(t) return nil } return fmt.Errorf("error parsing time string %s: %w", timeString, err) } + +func ToJSONTime(timeString string) JSONTime { + t, err := time.Parse(DefaultDateLayout, timeString) + if err != nil { + slog.Error("error parsing time string: ", "error", err) + return JSONTime(time.Time{}) + } + return JSONTime(t) +} diff --git a/services/ical/service/connector/feedConnector.go b/services/ical/service/connector/feedConnector.go index acd3abd..35b7f1a 100644 --- a/services/ical/service/connector/feedConnector.go +++ b/services/ical/service/connector/feedConnector.go @@ -7,12 +7,12 @@ import ( "log/slog" ) -func GetFeedByToken(token string) (model.FeedRecord, error) { +func GetFeedByToken(host string, token string) (model.FeedRecord, error) { var feed model.FeedRecord // /api/collections/feeds/records/{id} - response, err := RequestApi("/api/collections/feeds/records/" + token) + response, err := RequestApi(host, "/api/collections/feeds/records/"+token) if err != nil { return model.FeedRecord{}, err } @@ -39,8 +39,8 @@ func parseResponse(response []byte) (model.FeedRecord, error) { return feedRecord, nil } -func DeleteFeedRecord(token string) error { - err := DeleteRequestApi("/api/feed?token=" + token) +func DeleteFeedRecord(app model.AppType, token string) error { + err := DeleteRequestApi(app.DataManagerURL, "/api/feed?token="+token) if err != nil { return err } @@ -48,10 +48,10 @@ func DeleteFeedRecord(token string) error { return nil } -func GetModuleWithEvents(module model.FeedModule) (model.Module, error) { +func GetModuleWithEvents(app model.AppType, module model.FeedModule) (model.Module, error) { var modules model.Module - response, err := RequestApi("/api/module?uuid=" + module.UUID) + response, err := RequestApi(app.DataManagerURL, "/api/module?uuid="+module.UUID) if err != nil { return model.Module{}, err } @@ -77,10 +77,10 @@ func parseModuleResponse(body []byte) (model.Module, error) { return module, nil } -func SaveFeedRecord(modules []model.FeedCollection) (string, error) { +func SaveFeedRecord(app model.AppType, modules []model.FeedCollection) (string, error) { var token string - response, err := PostRequestApi("/api/feed", modules) + response, err := PostRequestApi(app.DataManagerURL, "/api/feed", modules) if err != nil { return "", err } diff --git a/services/ical/service/connector/grpc/client.go b/services/ical/service/connector/grpc/client.go new file mode 100644 index 0000000..3b3b92c --- /dev/null +++ b/services/ical/service/connector/grpc/client.go @@ -0,0 +1,21 @@ +package grpc + +import ( + "google.golang.org/grpc" + "log/slog" +) + +func ConnectGRPCServer(host string) *grpc.ClientConn { + conn, err := grpc.Dial(host+":50051", grpc.WithInsecure(), grpc.WithBlock()) + if err != nil { + slog.Error("could not connect to grpc server", "error", err) + } + return conn +} + +func CloseGRPCServer(conn *grpc.ClientConn) { + err := conn.Close() + if err != nil { + slog.Error("could not close connection", "error", err) + } +} diff --git a/services/ical/service/connector/grpc/modules.go b/services/ical/service/connector/grpc/modules.go new file mode 100644 index 0000000..0574cf7 --- /dev/null +++ b/services/ical/service/connector/grpc/modules.go @@ -0,0 +1,54 @@ +package grpc + +import ( + "context" + "google.golang.org/grpc" + pb "htwkalender/common/genproto/modules" + "htwkalender/ical/model" + "log/slog" + "time" +) + +func GetModuleWithEvents(module model.FeedModule, conn *grpc.ClientConn) (model.Module, error) { + c := pb.NewModuleServiceClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.GetModule(ctx, &pb.GetModuleRequest{Uuid: module.UUID}) + if err != nil { + slog.Error("could not get module: %v", "error", err) + } + + events := make([]model.Event, 0) + for _, event := range r.GetModule().Events { + events = append(events, protoToEvent(event)) + } + + return model.Module{ + UUID: r.GetModule().Uuid, + Name: r.GetModule().Name, + Prof: r.GetModule().Prof, + Course: r.GetModule().Course, + Semester: r.GetModule().Semester, + Events: events, + }, nil +} + +func protoToEvent(event *pb.Event) model.Event { + + return model.Event{ + UUID: event.Uuid, + Day: event.Day, + Week: event.Week, + Start: model.ToJSONTime(event.Start), + End: model.ToJSONTime(event.End), + Name: event.Name, + EventType: event.EventType, + Compulsory: event.Compulsory, + Prof: event.Prof, + Rooms: event.Rooms, + Notes: event.Notes, + BookedAt: event.BookedAt, + Course: event.Course, + Semester: event.Semester, + } +} diff --git a/services/ical/service/connector/restHandler.go b/services/ical/service/connector/restHandler.go index 89d1385..4af7ba0 100644 --- a/services/ical/service/connector/restHandler.go +++ b/services/ical/service/connector/restHandler.go @@ -6,9 +6,7 @@ import ( "time" ) -const host = "http://htwkalender-data-manager:8090" - -func RequestApi(path string) (*client.Response, error) { +func RequestApi(host string, path string) (*client.Response, error) { cc := client.New() cc.SetTimeout(5 * time.Second) @@ -22,7 +20,7 @@ func RequestApi(path string) (*client.Response, error) { return response, nil } -func DeleteRequestApi(path string) error { +func DeleteRequestApi(host string, path string) error { cc := client.New() cc.SetTimeout(5 * time.Second) @@ -36,7 +34,7 @@ func DeleteRequestApi(path string) error { return nil } -func PostRequestApi(path string, body []model.FeedCollection) (*client.Response, error) { +func PostRequestApi(host string, path string, body []model.FeedCollection) (*client.Response, error) { cc := client.New() cc.SetTimeout(5 * time.Second) diff --git a/services/ical/service/ical/ical.go b/services/ical/service/ical/ical.go index 0ffd6ab..42f2227 100644 --- a/services/ical/service/ical/ical.go +++ b/services/ical/service/ical/ical.go @@ -5,15 +5,16 @@ import ( "github.com/jordic/goics" "htwkalender/ical/model" "htwkalender/ical/service/connector" + htwkalenderGrpc "htwkalender/ical/service/connector/grpc" "log/slog" "time" ) const expirationTime = 5 * time.Minute -func Feed(token string) (string, error) { +func Feed(app model.AppType, token string) (string, error) { // get feed by token - feed, err := connector.GetFeedByToken(token) + feed, err := connector.GetFeedByToken(app.DataManagerURL, token) if err != nil { return "", err } @@ -21,7 +22,7 @@ func Feed(token string) (string, error) { var events model.Events for _, module := range feed.Modules { - moduleWithEvents, err := connector.GetModuleWithEvents(module) + moduleWithEvents, err := htwkalenderGrpc.GetModuleWithEvents(module, app.GrpcClient) if err != nil { return "", err } @@ -29,7 +30,7 @@ func Feed(token string) (string, error) { events = append(events, moduleWithEvents.Events...) } - // Sorte events by start date + // Sort events by start date events.Sort() modules := make(map[string]model.FeedCollection) @@ -44,9 +45,9 @@ func Feed(token string) (string, error) { return icalFeed.Content, nil } -func FeedRecord(token string) (model.FeedRecord, error) { +func FeedRecord(app model.AppType, token string) (model.FeedRecord, error) { - feedRecord, err := connector.GetFeedByToken(token) + feedRecord, err := connector.GetFeedByToken(app.DataManagerURL, token) if err != nil { return model.FeedRecord{}, err } @@ -55,18 +56,18 @@ func FeedRecord(token string) (model.FeedRecord, error) { } -func DeleteFeedRecord(token string) error { - err := connector.DeleteFeedRecord(token) +func DeleteFeedRecord(app model.AppType, token string) error { + err := connector.DeleteFeedRecord(app, token) if err != nil { return err } return nil } -func CreateFeed(modules []model.FeedCollection) (string, error) { +func CreateFeed(app model.AppType, modules []model.FeedCollection) (string, error) { // Save feed - token, err := connector.SaveFeedRecord(modules) + token, err := connector.SaveFeedRecord(app, modules) if err != nil { slog.Error("Failed to save feed", "error", err) return "", err diff --git a/services/ical/service/routes.go b/services/ical/service/routes.go index 5bd1eed..7e2088f 100644 --- a/services/ical/service/routes.go +++ b/services/ical/service/routes.go @@ -12,13 +12,13 @@ import ( // AddFeedRoutes add routes to the app instance for the data-manager ical service // with golang fiber -func AddFeedRoutes(app *fiber.App) { +func AddFeedRoutes(app model.AppType) { // Define a route for the GET method on the root path '/' - app.Get("/api/feed", func(c fiber.Ctx) error { + app.Fiber.Get("/api/feed", func(c fiber.Ctx) error { token := c.Query("token") - results, err := ical.Feed(token) + results, err := ical.Feed(app, token) if err != nil { slog.Error("Failed to get feed", "error", err) @@ -33,7 +33,7 @@ func AddFeedRoutes(app *fiber.App) { }) // Define a route for the POST method on the root path '/api/feed' - app.Post("/api/feed", func(c fiber.Ctx) error { + app.Fiber.Post("/api/feed", func(c fiber.Ctx) error { var modules []model.FeedCollection //obtain the body of the request err := json.Unmarshal(c.Body(), &modules) @@ -43,7 +43,7 @@ func AddFeedRoutes(app *fiber.App) { } //create a new feed - token, err := ical.CreateFeed(modules) + token, err := ical.CreateFeed(app, modules) if err != nil { println(err) log.Error("Failed to create feed", "error", err) @@ -54,10 +54,10 @@ func AddFeedRoutes(app *fiber.App) { }) // Define a route for the GET method on the root path '/' - app.Get("/api/collections/feeds/records/:token", func(c fiber.Ctx) error { + app.Fiber.Get("/api/collections/feeds/records/:token", func(c fiber.Ctx) error { token := c.Params("token") - results, err := ical.FeedRecord(token) + results, err := ical.FeedRecord(app, token) if err != nil { slog.Error("Failed to get feed", "error", err) @@ -68,10 +68,10 @@ func AddFeedRoutes(app *fiber.App) { return c.JSON(results) }) - app.Delete("/api/feed", func(c fiber.Ctx) error { + app.Fiber.Delete("/api/feed", func(c fiber.Ctx) error { token := c.Query("token") - err := ical.DeleteFeedRecord(token) + err := ical.DeleteFeedRecord(app, token) if err != nil { slog.Error("Feed could not be deleted", "error", err) return c.JSON(http.StatusNotFound, "Feed could not be deleted") @@ -80,28 +80,28 @@ func AddFeedRoutes(app *fiber.App) { } }) - app.Put("/api/feed", func(c fiber.Ctx) error { + app.Fiber.Put("/api/feed", func(c fiber.Ctx) error { token := c.Query("token") return c.JSON(http.StatusOK, "token: "+token) }) - app.Head("/api/feed", func(c fiber.Ctx) error { + app.Fiber.Head("/api/feed", func(c fiber.Ctx) error { return c.JSON(http.StatusOK, "") }) - app.Add([]string{"PROPFIND"}, "/api/feed", func(c fiber.Ctx) error { + app.Fiber.Add([]string{"PROPFIND"}, "/api/feed", func(c fiber.Ctx) error { return c.JSON(http.StatusOK, "") }) // Route for Thunderbird to get calendar server information // Response is a 200 OK without additional content - app.Add([]string{"PROPFIND"}, "/.well-known/caldav", func(c fiber.Ctx) error { + app.Fiber.Add([]string{"PROPFIND"}, "/.well-known/caldav", func(c fiber.Ctx) error { return c.JSON(http.StatusOK, "") }) // Route for Thunderbird to get calendar server information // Response is a 200 OK without additional content - app.Add([]string{"PROPFIND"}, "/", func(c fiber.Ctx) error { + app.Fiber.Add([]string{"PROPFIND"}, "/", func(c fiber.Ctx) error { return c.JSON(http.StatusOK, "") }) diff --git a/services/protobuf/modules.proto b/services/protobuf/modules.proto index cfeba31..1b608bd 100644 --- a/services/protobuf/modules.proto +++ b/services/protobuf/modules.proto @@ -37,5 +37,5 @@ message GetModuleRequest { } message GetModuleResponse { - repeated Module module = 1; + Module module = 1; } \ No newline at end of file From 27884ff06a5bc8c36027797ba35856869adada3e Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Mon, 17 Jun 2024 01:01:52 +0200 Subject: [PATCH 04/18] feat:#36 updated gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c66e6eb..871e43c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ .DS_Store workspace.xml **/.idea/ -.sass-cache/ \ No newline at end of file +.sass-cache/ +/services/pb_data/ From 56e77630b501b3d647b6efd213eada48f4cd00d6 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Mon, 17 Jun 2024 01:13:52 +0200 Subject: [PATCH 05/18] fix:#36 updated linting error --- services/ical/service/connector/grpc/client.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/ical/service/connector/grpc/client.go b/services/ical/service/connector/grpc/client.go index 3b3b92c..f9c7275 100644 --- a/services/ical/service/connector/grpc/client.go +++ b/services/ical/service/connector/grpc/client.go @@ -2,11 +2,12 @@ package grpc import ( "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "log/slog" ) func ConnectGRPCServer(host string) *grpc.ClientConn { - conn, err := grpc.Dial(host+":50051", grpc.WithInsecure(), grpc.WithBlock()) + conn, err := grpc.Dial(host+":50051", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { slog.Error("could not connect to grpc server", "error", err) } From 08140b5802fe04e6788bbb55de0d229c5e85f35e Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Tue, 18 Jun 2024 12:50:21 +0200 Subject: [PATCH 06/18] feat:#36 added new event grpc message --- services/Makefile | 4 +- services/README.md | 6 + .../common/genproto/modules/modules.pb.go | 257 ++++++++++++++++-- .../genproto/modules/modules_grpc.pb.go | 72 +++++ services/data-manager/service/db/dbEvents.go | 30 +- .../data-manager/service/db/dbEvents_test.go | 9 +- .../data-manager/service/db/dbFunctions.go | 17 ++ .../service/db/dbFunctions_test.go | 50 ++++ services/data-manager/service/grpc/mapper.go | 8 + services/data-manager/service/grpc/server.go | 12 + .../ical/service/connector/grpc/events.go | 34 +++ .../ical/service/connector/grpc/modules.go | 36 +++ services/ical/service/ical/ical.go | 11 +- services/protobuf/modules.proto | 14 + 14 files changed, 510 insertions(+), 50 deletions(-) create mode 100644 services/README.md create mode 100644 services/data-manager/service/db/dbFunctions_test.go create mode 100644 services/ical/service/connector/grpc/events.go diff --git a/services/Makefile b/services/Makefile index 526dddd..94269fa 100644 --- a/services/Makefile +++ b/services/Makefile @@ -10,7 +10,7 @@ build-ical: gen: @protoc \ --proto_path=protobuf "protobuf/modules.proto" \ - --go_out=common/genproto/modules \ + --go_out="common/genproto/modules" \ --go_opt=paths=source_relative \ - --go-grpc_out=common/genproto/modules \ + --go-grpc_out="common/genproto/modules" \ --go-grpc_opt=paths=source_relative \ No newline at end of file diff --git a/services/README.md b/services/README.md new file mode 100644 index 0000000..c309315 --- /dev/null +++ b/services/README.md @@ -0,0 +1,6 @@ +To execute the protobuf gen script, install the protobuf compiler and the python protobuf library. Then run the following command: + +```bash +go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 +``` diff --git a/services/common/genproto/modules/modules.pb.go b/services/common/genproto/modules/modules.pb.go index cc88a8b..3ce1b6b 100644 --- a/services/common/genproto/modules/modules.pb.go +++ b/services/common/genproto/modules/modules.pb.go @@ -305,6 +305,53 @@ func (x *GetModuleRequest) GetUuid() string { return "" } +type GetModulesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uuids []string `protobuf:"bytes,1,rep,name=uuids,proto3" json:"uuids,omitempty"` +} + +func (x *GetModulesRequest) Reset() { + *x = GetModulesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetModulesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModulesRequest) ProtoMessage() {} + +func (x *GetModulesRequest) ProtoReflect() protoreflect.Message { + mi := &file_modules_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModulesRequest.ProtoReflect.Descriptor instead. +func (*GetModulesRequest) Descriptor() ([]byte, []int) { + return file_modules_proto_rawDescGZIP(), []int{3} +} + +func (x *GetModulesRequest) GetUuids() []string { + if x != nil { + return x.Uuids + } + return nil +} + type GetModuleResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -316,7 +363,7 @@ type GetModuleResponse struct { func (x *GetModuleResponse) Reset() { *x = GetModuleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_modules_proto_msgTypes[3] + mi := &file_modules_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -329,7 +376,7 @@ func (x *GetModuleResponse) String() string { func (*GetModuleResponse) ProtoMessage() {} func (x *GetModuleResponse) ProtoReflect() protoreflect.Message { - mi := &file_modules_proto_msgTypes[3] + mi := &file_modules_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -342,7 +389,7 @@ func (x *GetModuleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetModuleResponse.ProtoReflect.Descriptor instead. func (*GetModuleResponse) Descriptor() ([]byte, []int) { - return file_modules_proto_rawDescGZIP(), []int{3} + return file_modules_proto_rawDescGZIP(), []int{4} } func (x *GetModuleResponse) GetModule() *Module { @@ -352,6 +399,100 @@ func (x *GetModuleResponse) GetModule() *Module { return nil } +type GetModulesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Modules []*Module `protobuf:"bytes,1,rep,name=modules,proto3" json:"modules,omitempty"` +} + +func (x *GetModulesResponse) Reset() { + *x = GetModulesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetModulesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModulesResponse) ProtoMessage() {} + +func (x *GetModulesResponse) ProtoReflect() protoreflect.Message { + mi := &file_modules_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModulesResponse.ProtoReflect.Descriptor instead. +func (*GetModulesResponse) Descriptor() ([]byte, []int) { + return file_modules_proto_rawDescGZIP(), []int{5} +} + +func (x *GetModulesResponse) GetModules() []*Module { + if x != nil { + return x.Modules + } + return nil +} + +type GetEventsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Events []*Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` +} + +func (x *GetEventsResponse) Reset() { + *x = GetEventsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_modules_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetEventsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEventsResponse) ProtoMessage() {} + +func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { + mi := &file_modules_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEventsResponse.ProtoReflect.Descriptor instead. +func (*GetEventsResponse) Descriptor() ([]byte, []int) { + return file_modules_proto_rawDescGZIP(), []int{6} +} + +func (x *GetEventsResponse) GetEvents() []*Event { + if x != nil { + return x.Events + } + return nil +} + var File_modules_proto protoreflect.FileDescriptor var file_modules_proto_rawDesc = []byte{ @@ -389,17 +530,34 @@ var file_modules_proto_rawDesc = []byte{ 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x26, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, - 0x22, 0x34, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x32, 0x45, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x12, 0x11, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1c, 0x5a, - 0x1a, 0x68, 0x74, 0x77, 0x6b, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x22, 0x29, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x75, 0x69, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x75, 0x75, 0x69, 0x64, 0x73, 0x22, 0x34, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1f, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x07, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x22, 0x37, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x33, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1e, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x32, + 0xbf, 0x01, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x34, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x11, + 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x47, 0x65, 0x74, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x3f, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x47, 0x65, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0x1c, 0x5a, 0x1a, 0x68, 0x74, 0x77, 0x6b, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -414,23 +572,32 @@ func file_modules_proto_rawDescGZIP() []byte { return file_modules_proto_rawDescData } -var file_modules_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_modules_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_modules_proto_goTypes = []interface{}{ - (*Event)(nil), // 0: Event - (*Module)(nil), // 1: Module - (*GetModuleRequest)(nil), // 2: GetModuleRequest - (*GetModuleResponse)(nil), // 3: GetModuleResponse + (*Event)(nil), // 0: Event + (*Module)(nil), // 1: Module + (*GetModuleRequest)(nil), // 2: GetModuleRequest + (*GetModulesRequest)(nil), // 3: GetModulesRequest + (*GetModuleResponse)(nil), // 4: GetModuleResponse + (*GetModulesResponse)(nil), // 5: GetModulesResponse + (*GetEventsResponse)(nil), // 6: GetEventsResponse } var file_modules_proto_depIdxs = []int32{ 0, // 0: Module.events:type_name -> Event 1, // 1: GetModuleResponse.module:type_name -> Module - 2, // 2: ModuleService.GetModule:input_type -> GetModuleRequest - 3, // 3: ModuleService.GetModule:output_type -> GetModuleResponse - 3, // [3:4] is the sub-list for method output_type - 2, // [2:3] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 1, // 2: GetModulesResponse.modules:type_name -> Module + 0, // 3: GetEventsResponse.events:type_name -> Event + 2, // 4: ModuleService.GetModule:input_type -> GetModuleRequest + 3, // 5: ModuleService.GetModules:input_type -> GetModulesRequest + 3, // 6: ModuleService.GetEventsForModules:input_type -> GetModulesRequest + 4, // 7: ModuleService.GetModule:output_type -> GetModuleResponse + 5, // 8: ModuleService.GetModules:output_type -> GetModulesResponse + 6, // 9: ModuleService.GetEventsForModules:output_type -> GetEventsResponse + 7, // [7:10] is the sub-list for method output_type + 4, // [4:7] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_modules_proto_init() } @@ -476,6 +643,18 @@ func file_modules_proto_init() { } } file_modules_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetModulesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetModuleResponse); i { case 0: return &v.state @@ -487,6 +666,30 @@ func file_modules_proto_init() { return nil } } + file_modules_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetModulesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_modules_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEventsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -494,7 +697,7 @@ func file_modules_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_modules_proto_rawDesc, NumEnums: 0, - NumMessages: 4, + NumMessages: 7, NumExtensions: 0, NumServices: 1, }, diff --git a/services/common/genproto/modules/modules_grpc.pb.go b/services/common/genproto/modules/modules_grpc.pb.go index eafc547..5c6a689 100644 --- a/services/common/genproto/modules/modules_grpc.pb.go +++ b/services/common/genproto/modules/modules_grpc.pb.go @@ -23,6 +23,8 @@ const _ = grpc.SupportPackageIsVersion7 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ModuleServiceClient interface { GetModule(ctx context.Context, in *GetModuleRequest, opts ...grpc.CallOption) (*GetModuleResponse, error) + GetModules(ctx context.Context, in *GetModulesRequest, opts ...grpc.CallOption) (*GetModulesResponse, error) + GetEventsForModules(ctx context.Context, in *GetModulesRequest, opts ...grpc.CallOption) (*GetEventsResponse, error) } type moduleServiceClient struct { @@ -42,11 +44,31 @@ func (c *moduleServiceClient) GetModule(ctx context.Context, in *GetModuleReques return out, nil } +func (c *moduleServiceClient) GetModules(ctx context.Context, in *GetModulesRequest, opts ...grpc.CallOption) (*GetModulesResponse, error) { + out := new(GetModulesResponse) + err := c.cc.Invoke(ctx, "/ModuleService/GetModules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *moduleServiceClient) GetEventsForModules(ctx context.Context, in *GetModulesRequest, opts ...grpc.CallOption) (*GetEventsResponse, error) { + out := new(GetEventsResponse) + err := c.cc.Invoke(ctx, "/ModuleService/GetEventsForModules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ModuleServiceServer is the server API for ModuleService service. // All implementations must embed UnimplementedModuleServiceServer // for forward compatibility type ModuleServiceServer interface { GetModule(context.Context, *GetModuleRequest) (*GetModuleResponse, error) + GetModules(context.Context, *GetModulesRequest) (*GetModulesResponse, error) + GetEventsForModules(context.Context, *GetModulesRequest) (*GetEventsResponse, error) mustEmbedUnimplementedModuleServiceServer() } @@ -57,6 +79,12 @@ type UnimplementedModuleServiceServer struct { func (UnimplementedModuleServiceServer) GetModule(context.Context, *GetModuleRequest) (*GetModuleResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetModule not implemented") } +func (UnimplementedModuleServiceServer) GetModules(context.Context, *GetModulesRequest) (*GetModulesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetModules not implemented") +} +func (UnimplementedModuleServiceServer) GetEventsForModules(context.Context, *GetModulesRequest) (*GetEventsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetEventsForModules not implemented") +} func (UnimplementedModuleServiceServer) mustEmbedUnimplementedModuleServiceServer() {} // UnsafeModuleServiceServer may be embedded to opt out of forward compatibility for this service. @@ -88,6 +116,42 @@ func _ModuleService_GetModule_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _ModuleService_GetModules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetModulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ModuleServiceServer).GetModules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ModuleService/GetModules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ModuleServiceServer).GetModules(ctx, req.(*GetModulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ModuleService_GetEventsForModules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetModulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ModuleServiceServer).GetEventsForModules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ModuleService/GetEventsForModules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ModuleServiceServer).GetEventsForModules(ctx, req.(*GetModulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ModuleService_ServiceDesc is the grpc.ServiceDesc for ModuleService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -99,6 +163,14 @@ var ModuleService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetModule", Handler: _ModuleService_GetModule_Handler, }, + { + MethodName: "GetModules", + Handler: _ModuleService_GetModules_Handler, + }, + { + MethodName: "GetEventsForModules", + Handler: _ModuleService_GetEventsForModules_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "modules.proto", diff --git a/services/data-manager/service/db/dbEvents.go b/services/data-manager/service/db/dbEvents.go index 2296de8..0686695 100644 --- a/services/data-manager/service/db/dbEvents.go +++ b/services/data-manager/service/db/dbEvents.go @@ -131,25 +131,37 @@ func findEventByDayWeekStartEndNameCourse(event model.Event, course string, dao } } -func buildIcalQueryForModules(modules []model.FeedCollection) dbx.Expression { +func buildIcalQueryForModules(modulesUuid []string) dbx.Expression { + + // check uuids against sql injection + // uuids are generated by the system and are not user input + // following the pattern of only containing alphanumeric characters and dashes + + for _, moduleUuid := range modulesUuid { + if !IsSafeIdentifier(moduleUuid) { + slog.Warn("Module UUID is not safe: ", "moduleUuid", moduleUuid) + return dbx.HashExp{} + } + + } // build where conditions for each module //first check if modules is empty - if len(modules) == 0 { + if len(modulesUuid) == 0 { return dbx.HashExp{} } //second check if modules has only one element - if len(modules) == 1 { - return dbx.HashExp{"uuid": modules[0].UUID} + if len(modulesUuid) == 1 { + return dbx.HashExp{"uuid": modulesUuid[0]} } //third check if modules has more than one element var wheres []dbx.Expression - for _, module := range modules { - where := dbx.HashExp{"uuid": module.UUID} + for _, moduleUuid := range modulesUuid { + where := dbx.HashExp{"uuid": moduleUuid} wheres = append(wheres, where) } @@ -162,18 +174,18 @@ func buildIcalQueryForModules(modules []model.FeedCollection) dbx.Expression { // GetPlanForModules returns all events for the given modules with the given course // used for the ical feed -func GetPlanForModules(app *pocketbase.PocketBase, modules map[string]model.FeedCollection) (model.Events, error) { +func GetPlanForModules(app *pocketbase.PocketBase, modules []string) (model.Events, error) { var events model.Events - modulesArray := make([]model.FeedCollection, 0, len(modules)) + modulesArray := make([]string, 0, len(modules)) for _, value := range modules { modulesArray = append(modulesArray, value) } // iterate over modules in 100 batch sizes for i := 0; i < len(modules); i += 100 { - var moduleBatch []model.FeedCollection + var moduleBatch []string if i+100 > len(modules) { moduleBatch = modulesArray[i:] diff --git a/services/data-manager/service/db/dbEvents_test.go b/services/data-manager/service/db/dbEvents_test.go index 14542e0..5941c58 100644 --- a/services/data-manager/service/db/dbEvents_test.go +++ b/services/data-manager/service/db/dbEvents_test.go @@ -18,14 +18,13 @@ package db import ( "github.com/pocketbase/dbx" - "htwkalender/data-manager/model" "reflect" "testing" ) func Test_buildIcalQueryForModules(t *testing.T) { type args struct { - modules []model.FeedCollection + modules []string } tests := []struct { name string @@ -34,17 +33,17 @@ func Test_buildIcalQueryForModules(t *testing.T) { }{ { name: "empty modules", - args: args{modules: []model.FeedCollection{}}, + args: args{modules: []string{}}, want: dbx.HashExp{}, }, { name: "one module", - args: args{modules: []model.FeedCollection{{Name: "test", Course: "test", UUID: "test"}}}, + args: args{modules: []string{"test"}}, want: dbx.HashExp{"uuid": "test"}, }, { name: "two modules", - args: args{modules: []model.FeedCollection{{Name: "test", Course: "test", UUID: "test"}, {Name: "test2", Course: "test2", UUID: "test2"}}}, + args: args{modules: []string{"test", "test2"}}, want: dbx.Or(dbx.HashExp{"uuid": "test"}, dbx.HashExp{"uuid": "test2"}), }, } diff --git a/services/data-manager/service/db/dbFunctions.go b/services/data-manager/service/db/dbFunctions.go index 05cd48b..3f6f2b6 100644 --- a/services/data-manager/service/db/dbFunctions.go +++ b/services/data-manager/service/db/dbFunctions.go @@ -19,9 +19,26 @@ package db import ( "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/models" + "log/slog" + "regexp" ) func FindCollection(app *pocketbase.PocketBase, collectionName string) (*models.Collection, error) { collection, dbError := app.Dao().FindCollectionByNameOrId(collectionName) return collection, dbError } + +// IsSafeIdentifier check uuids against sql injection +// uuids are generated by the system and are not user input +// following the pattern of only containing alphanumeric characters and dashes +func IsSafeIdentifier(uuid string) bool { + // Define a regular expression that matches only valid UUID characters (alphanumeric and dashes) + validUUIDPattern := `^[a-zA-Z0-9-]+$` + match, err := regexp.MatchString(validUUIDPattern, uuid) + if err != nil { + // Handle the error according to your application's needs + slog.Warn("Invalid UUID pattern", "uuid", uuid) + return false + } + return match +} diff --git a/services/data-manager/service/db/dbFunctions_test.go b/services/data-manager/service/db/dbFunctions_test.go new file mode 100644 index 0000000..2f1612f --- /dev/null +++ b/services/data-manager/service/db/dbFunctions_test.go @@ -0,0 +1,50 @@ +package db + +import "testing" + +func TestIsSafeIdentifier(t *testing.T) { + type args struct { + uuid string + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "Test safe identifier", + args: args{ + uuid: "1234567890-1234567890-1234567890-1234567890", + }, + want: true, + }, + { + name: "Test safe identifier", + args: args{ + uuid: "1234567890-1234567890-1234567890-1234567890", + }, + want: true, + }, + { + name: "Test safe identifier", + args: args{ + uuid: "77eddc32-c49d-5d0a-8c36-17b266396641", + }, + want: true, + }, + { + name: "Test unsafe identifier", + args: args{ + uuid: "77eddc32-c49d-5d0a-8c36-17/1!!b266396641-", + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IsSafeIdentifier(tt.args.uuid); got != tt.want { + t.Errorf("IsSafeIdentifier() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/services/data-manager/service/grpc/mapper.go b/services/data-manager/service/grpc/mapper.go index b352d45..01f439c 100644 --- a/services/data-manager/service/grpc/mapper.go +++ b/services/data-manager/service/grpc/mapper.go @@ -23,3 +23,11 @@ func eventToProto(event *model.Event) *pb.Event { Semester: event.Semester, } } + +func eventsToProto(events model.Events) []*pb.Event { + protoEvents := make([]*pb.Event, 0) + for _, event := range events { + protoEvents = append(protoEvents, eventToProto(&event)) + } + return protoEvents +} diff --git a/services/data-manager/service/grpc/server.go b/services/data-manager/service/grpc/server.go index 9ad33f9..7841b5e 100644 --- a/services/data-manager/service/grpc/server.go +++ b/services/data-manager/service/grpc/server.go @@ -67,3 +67,15 @@ func StartGRPCServer(app *pocketbase.PocketBase) { log.Fatalf("failed to serve: %v", err) } } + +func (s *ModulesGrpcHandler) GetEventsForModules(ctx context.Context, in *pb.GetModulesRequest) (*pb.GetEventsResponse, error) { + + events, err := db.GetPlanForModules(s.app, in.Uuids) + if err != nil { + return nil, err + } + + return &pb.GetEventsResponse{ + Events: eventsToProto(events), + }, nil +} diff --git a/services/ical/service/connector/grpc/events.go b/services/ical/service/connector/grpc/events.go new file mode 100644 index 0000000..fc82755 --- /dev/null +++ b/services/ical/service/connector/grpc/events.go @@ -0,0 +1,34 @@ +package grpc + +import ( + "context" + "google.golang.org/grpc" + pb "htwkalender/common/genproto/modules" + "htwkalender/ical/model" + "log/slog" + "time" +) + +func GetEvents(modules []model.FeedModule, conn *grpc.ClientConn) (model.Events, error) { + c := pb.NewModuleServiceClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + // List of uuids + uuids := make([]string, 0) + for _, module := range modules { + uuids = append(uuids, module.UUID) + } + + r, err := c.GetEventsForModules(ctx, &pb.GetModulesRequest{Uuids: uuids}) + if err != nil { + slog.Error("could not get modules: %v", "error", err) + } + + events := make(model.Events, 0) + for _, event := range r.GetEvents() { + events = append(events, protoToEvent(event)) + } + + return events, nil +} diff --git a/services/ical/service/connector/grpc/modules.go b/services/ical/service/connector/grpc/modules.go index 0574cf7..aa47d79 100644 --- a/services/ical/service/connector/grpc/modules.go +++ b/services/ical/service/connector/grpc/modules.go @@ -33,6 +33,42 @@ func GetModuleWithEvents(module model.FeedModule, conn *grpc.ClientConn) (model. }, nil } +func GetModulesWithEvents(modules []model.FeedModule, conn *grpc.ClientConn) ([]model.Module, error) { + c := pb.NewModuleServiceClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + // List of uuids + uuids := make([]string, 0) + for _, module := range modules { + uuids = append(uuids, module.UUID) + } + + r, err := c.GetModules(ctx, &pb.GetModulesRequest{Uuids: uuids}) + if err != nil { + slog.Error("could not get modules: %v", "error", err) + } + + moduleList := make([]model.Module, 0) + for _, module := range r.GetModules() { + events := make([]model.Event, 0) + for _, event := range module.Events { + events = append(events, protoToEvent(event)) + } + + moduleList = append(moduleList, model.Module{ + UUID: module.Uuid, + Name: module.Name, + Prof: module.Prof, + Course: module.Course, + Semester: module.Semester, + Events: events, + }) + } + + return moduleList, nil +} + func protoToEvent(event *pb.Event) model.Event { return model.Event{ diff --git a/services/ical/service/ical/ical.go b/services/ical/service/ical/ical.go index 42f2227..be57533 100644 --- a/services/ical/service/ical/ical.go +++ b/services/ical/service/ical/ical.go @@ -21,13 +21,10 @@ func Feed(app model.AppType, token string) (string, error) { var events model.Events - for _, module := range feed.Modules { - moduleWithEvents, err := htwkalenderGrpc.GetModuleWithEvents(module, app.GrpcClient) - if err != nil { - return "", err - } - - events = append(events, moduleWithEvents.Events...) + // Get all events for modules + events, err = htwkalenderGrpc.GetEvents(feed.Modules, app.GrpcClient) + if err != nil { + return "", err } // Sort events by start date diff --git a/services/protobuf/modules.proto b/services/protobuf/modules.proto index 1b608bd..1ba6c27 100644 --- a/services/protobuf/modules.proto +++ b/services/protobuf/modules.proto @@ -4,6 +4,8 @@ option go_package = "htwkalender/common/modules"; service ModuleService { rpc GetModule(GetModuleRequest) returns (GetModuleResponse) {} + rpc GetModules(GetModulesRequest) returns (GetModulesResponse) {} + rpc GetEventsForModules(GetModulesRequest) returns (GetEventsResponse) {} } message Event { @@ -36,6 +38,18 @@ message GetModuleRequest { string uuid = 1; } +message GetModulesRequest { + repeated string uuids = 1; +} + message GetModuleResponse { Module module = 1; +} + +message GetModulesResponse { + repeated Module modules = 1; +} + +message GetEventsResponse { + repeated Event events = 1; } \ No newline at end of file From a87d911494f8a5d98d6f3e70271e482f5b9e37d5 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Tue, 18 Jun 2024 16:19:25 +0200 Subject: [PATCH 07/18] feat:#36 added real ip for proxy, extended error logging --- docker-compose.yml | 3 ++- reverseproxy.conf | 7 +++++ reverseproxy.dev.conf | 7 +++++ reverseproxy.local.conf | 7 +++++ services/data-manager/service/grpc/server.go | 13 +++++++--- services/go.mod | 6 +++++ services/go.sum | 8 ++++++ services/ical/main.go | 26 +++++++++++++------ .../ical/service/connector/feedConnector.go | 1 + services/ical/service/routes.go | 17 ++++++------ 10 files changed, 74 insertions(+), 21 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index eef364e..922610f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,7 +32,8 @@ services: dockerfile: ./ical/Dockerfile context: ./services target: dev # prod - + environment: + - DATA_MANAGER_URL=htwkalender-data-manager htwkalender-frontend: build: diff --git a/reverseproxy.conf b/reverseproxy.conf index c01c32c..86eb2dd 100644 --- a/reverseproxy.conf +++ b/reverseproxy.conf @@ -93,6 +93,13 @@ http { proxy_temp_file_write_size 64k; proxy_max_temp_file_size 1024m; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + geo $admin { default 1; 10.0.0.0/8 0; # Private Network diff --git a/reverseproxy.dev.conf b/reverseproxy.dev.conf index 7a6bf6b..ed8a7de 100644 --- a/reverseproxy.dev.conf +++ b/reverseproxy.dev.conf @@ -94,6 +94,13 @@ http { proxy_temp_file_write_size 64k; proxy_max_temp_file_size 1024m; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + geo $admin { default 1; 10.0.0.0/8 0; # Private Network diff --git a/reverseproxy.local.conf b/reverseproxy.local.conf index 16c5eba..8846d6d 100644 --- a/reverseproxy.local.conf +++ b/reverseproxy.local.conf @@ -50,6 +50,13 @@ http { proxy_temp_file_write_size 64k; proxy_max_temp_file_size 1024m; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + server { listen 80; diff --git a/services/data-manager/service/grpc/server.go b/services/data-manager/service/grpc/server.go index 7841b5e..edf3191 100644 --- a/services/data-manager/service/grpc/server.go +++ b/services/data-manager/service/grpc/server.go @@ -18,8 +18,12 @@ type ModulesGrpcHandler struct { func (s *ModulesGrpcHandler) GetModule(ctx context.Context, in *pb.GetModuleRequest) (*pb.GetModuleResponse, error) { - // get module from database by UUID + s.app.Logger().Info( + "Protobuf - GetModule", + "uuid", in.Uuid, + ) + // get module from database by UUID module, err := db.FindModuleByUUID(s.app, in.Uuid) if err != nil { return nil, err @@ -35,7 +39,6 @@ func (s *ModulesGrpcHandler) GetModule(ctx context.Context, in *pb.GetModuleRequ for _, event := range events { protoEvents = append(protoEvents, eventToProto(&event)) } - //map module to proto struct protoModule := &pb.Module{ Uuid: module.UUID, @@ -45,7 +48,6 @@ func (s *ModulesGrpcHandler) GetModule(ctx context.Context, in *pb.GetModuleRequ Semester: module.Semester, Events: protoEvents, } - // Implement your logic here to fetch module data based on the UUID // Example response return &pb.GetModuleResponse{ @@ -70,6 +72,11 @@ func StartGRPCServer(app *pocketbase.PocketBase) { func (s *ModulesGrpcHandler) GetEventsForModules(ctx context.Context, in *pb.GetModulesRequest) (*pb.GetEventsResponse, error) { + s.app.Logger().Info( + "Protobuf - GetEventsForModules", + "uuids", in.Uuids, + ) + events, err := db.GetPlanForModules(s.app, in.Uuids) if err != nil { return nil, err diff --git a/services/go.mod b/services/go.mod index 036f954..015e6a1 100644 --- a/services/go.mod +++ b/services/go.mod @@ -10,6 +10,7 @@ require ( github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 github.com/pocketbase/dbx v1.10.1 github.com/pocketbase/pocketbase v0.22.12 + github.com/samber/slog-fiber v1.15.3 golang.org/x/net v0.26.0 google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.34.1 @@ -47,6 +48,7 @@ require ( github.com/ganigeorgiev/fexpr v0.4.0 // indirect github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/gofiber/fiber/v2 v2.52.1 // indirect github.com/gofiber/utils/v2 v2.0.0-beta.4 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -58,10 +60,12 @@ require ( github.com/klauspost/compress v1.17.6 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -70,6 +74,8 @@ require ( github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/tcplisten v1.0.0 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect gocloud.dev v0.37.0 // indirect golang.org/x/crypto v0.24.0 // indirect golang.org/x/image v0.16.0 // indirect diff --git a/services/go.sum b/services/go.sum index 407fba5..2d8a28a 100644 --- a/services/go.sum +++ b/services/go.sum @@ -109,6 +109,8 @@ github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVH github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gofiber/fiber/v2 v2.52.1 h1:1RoU2NS+b98o1L77sdl5mboGPiW+0Ypsi5oLmcYlgHI= +github.com/gofiber/fiber/v2 v2.52.1/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= github.com/gofiber/fiber/v3 v3.0.0-beta.2 h1:mVVgt8PTaHGup3NGl/+7U7nEoZaXJ5OComV4E+HpAao= github.com/gofiber/fiber/v3 v3.0.0-beta.2/go.mod h1:w7sdfTY0okjZ1oVH6rSOGvuACUIt0By1iK0HKUb3uqM= github.com/gofiber/utils/v2 v2.0.0-beta.4 h1:1gjbVFFwVwUb9arPcqiB6iEjHBwo7cHsyS41NeIW3co= @@ -185,6 +187,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= @@ -202,9 +206,13 @@ github.com/pocketbase/pocketbase v0.22.12/go.mod h1:yY/3IGi1tUbcI6yGVFspAyKi/IDH github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/samber/slog-fiber v1.15.3 h1:RbfC0v2QPIEXoRdort2QxAsRG42LVaFTEgTNS/0GwRQ= +github.com/samber/slog-fiber v1.15.3/go.mod h1:I0b8eJ060SlpA65LXiqH7lZixUCkAPKiEGZqkT9QJOM= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= diff --git a/services/ical/main.go b/services/ical/main.go index b1a3138..353af6d 100644 --- a/services/ical/main.go +++ b/services/ical/main.go @@ -18,18 +18,25 @@ package main import ( "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/log" "github.com/gofiber/fiber/v3/middleware/logger" "htwkalender/ical/model" "htwkalender/ical/service" "htwkalender/ical/service/connector/grpc" + "log/slog" + "os" ) // main function for the ical service // uses rest api to get the data from the data-manager // exposes rest api endpoints with fiber to serve the data for clients func main() { - const host = "htwkalender-data-manager" + + // get host from env if this is not set use default value 127.0.0.1 + + host := os.Getenv("DATA_MANAGER_URL") + if host == "" { + host = "127.0.0.1" + } grpcClient := grpc.ConnectGRPCServer(host) defer grpc.CloseGRPCServer(grpcClient) @@ -38,11 +45,14 @@ func main() { webdavRequestMethods := []string{"PROPFIND", "MKCOL", "COPY", "MOVE"} fiberApp := fiber.New(fiber.Config{ - CaseSensitive: true, - StrictRouting: true, - ServerHeader: "Fiber", - AppName: "App Name", - RequestMethods: append(fiber.DefaultMethods[:], webdavRequestMethods...), + CaseSensitive: true, + StrictRouting: true, + ServerHeader: "HTWKalender iCal Service", + AppName: "HTWKalender iCal Service", + RequestMethods: append(fiber.DefaultMethods[:], webdavRequestMethods...), + EnableTrustedProxyCheck: true, + TrustedProxies: []string{"172.16.0.0/12", "172.18.0.5", "172.18.0.1"}, + ProxyHeader: "X-Forwarded-For", }) var app = model.AppType{ @@ -57,5 +67,5 @@ func main() { // Add routes to the app instance for the data-manager ical service service.AddFeedRoutes(app) - log.Fatal(fiberApp.Listen(":8091")) + slog.Info("Starting ical service", fiberApp.Listen(":8091")) } diff --git a/services/ical/service/connector/feedConnector.go b/services/ical/service/connector/feedConnector.go index 35b7f1a..e545791 100644 --- a/services/ical/service/connector/feedConnector.go +++ b/services/ical/service/connector/feedConnector.go @@ -14,6 +14,7 @@ func GetFeedByToken(host string, token string) (model.FeedRecord, error) { response, err := RequestApi(host, "/api/collections/feeds/records/"+token) if err != nil { + slog.Error("Failed to get feed record", "error", err) return model.FeedRecord{}, err } diff --git a/services/ical/service/routes.go b/services/ical/service/routes.go index 7e2088f..3aa0381 100644 --- a/services/ical/service/routes.go +++ b/services/ical/service/routes.go @@ -3,7 +3,6 @@ package service import ( "encoding/json" "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/log" "htwkalender/ical/model" "htwkalender/ical/service/ical" "log/slog" @@ -21,8 +20,8 @@ func AddFeedRoutes(app model.AppType) { results, err := ical.Feed(app, token) if err != nil { - slog.Error("Failed to get feed", "error", err) - return c.SendStatus(fiber.StatusInternalServerError) + slog.Error("Failed to get feed", "error", err, "token", token) + return c.SendStatus(fiber.StatusBadRequest) } c.Response().Header.Set("Content-type", "text/calendar") c.Response().Header.Set("charset", "utf-8") @@ -38,7 +37,7 @@ func AddFeedRoutes(app model.AppType) { //obtain the body of the request err := json.Unmarshal(c.Body(), &modules) if err != nil { - log.Error("Failed to unmarshal request body", "error", err) + slog.Error("Failed to parse request body", "error", err, "body", string(c.Body())) return c.SendStatus(fiber.StatusBadRequest) } @@ -46,8 +45,8 @@ func AddFeedRoutes(app model.AppType) { token, err := ical.CreateFeed(app, modules) if err != nil { println(err) - log.Error("Failed to create feed", "error", err) - return c.SendStatus(fiber.StatusInternalServerError) + slog.Error("Failed to create feed", "error", err) + return c.SendStatus(fiber.StatusBadRequest) } return c.JSON(token) @@ -60,8 +59,8 @@ func AddFeedRoutes(app model.AppType) { results, err := ical.FeedRecord(app, token) if err != nil { - slog.Error("Failed to get feed", "error", err) - return c.SendStatus(fiber.StatusInternalServerError) + slog.Error("Failed to get feed", "error", err, "token", token) + return c.SendStatus(fiber.StatusBadRequest) } c.Response().Header.Set("Content-type", "application/json; charset=UTF-8") @@ -73,7 +72,7 @@ func AddFeedRoutes(app model.AppType) { token := c.Query("token") err := ical.DeleteFeedRecord(app, token) if err != nil { - slog.Error("Feed could not be deleted", "error", err) + slog.Error("Feed could not be deleted", "error", err, "token", token) return c.JSON(http.StatusNotFound, "Feed could not be deleted") } else { return c.JSON(http.StatusOK, "Feed deleted") From 3f29cad8760cff8d70974c737e3f2805f9f96f28 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Tue, 18 Jun 2024 18:15:01 +0200 Subject: [PATCH 08/18] feat:#36 removed unnecessary map --- services/data-manager/service/db/dbEvents.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/services/data-manager/service/db/dbEvents.go b/services/data-manager/service/db/dbEvents.go index 0686695..f6cf5a2 100644 --- a/services/data-manager/service/db/dbEvents.go +++ b/services/data-manager/service/db/dbEvents.go @@ -178,19 +178,14 @@ func GetPlanForModules(app *pocketbase.PocketBase, modules []string) (model.Even var events model.Events - modulesArray := make([]string, 0, len(modules)) - for _, value := range modules { - modulesArray = append(modulesArray, value) - } - // iterate over modules in 100 batch sizes for i := 0; i < len(modules); i += 100 { var moduleBatch []string if i+100 > len(modules) { - moduleBatch = modulesArray[i:] + moduleBatch = modules[i:] } else { - moduleBatch = modulesArray[i : i+100] + moduleBatch = modules[i : i+100] } var selectedModulesQuery = buildIcalQueryForModules(moduleBatch) From 75752d3fb13b1c5b65f82c4238d6bc62747c516d Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Tue, 18 Jun 2024 18:18:14 +0200 Subject: [PATCH 09/18] feat:#36 fixed slog attribute --- services/ical/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ical/main.go b/services/ical/main.go index 353af6d..1769786 100644 --- a/services/ical/main.go +++ b/services/ical/main.go @@ -67,5 +67,5 @@ func main() { // Add routes to the app instance for the data-manager ical service service.AddFeedRoutes(app) - slog.Info("Starting ical service", fiberApp.Listen(":8091")) + slog.Info("Starting ical service", "fiberApp", fiberApp.Listen(":8091")) } From 4792b07e8c87863679c14a8d77e0d42f59fbc7e3 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Tue, 18 Jun 2024 18:53:29 +0200 Subject: [PATCH 10/18] fix:#36 fixed tests, naming, and removed old duplicated code --- services/data-manager/service/db/dbEvents.go | 5 +- .../data-manager/service/db/dbEvents_test.go | 8 +- .../data-manager/service/db/dbFunctions.go | 17 -- .../service/db/dbFunctions_test.go | 50 ---- .../data-manager/service/fetch/v2/fetcher.go | 2 + .../service/ical/icalFileGeneration.go | 173 ------------ .../service/ical/icalFileGeneration_test.go | 258 ------------------ .../service/ical/icsComponenter.go | 62 ----- 8 files changed, 9 insertions(+), 566 deletions(-) delete mode 100644 services/data-manager/service/db/dbFunctions_test.go delete mode 100644 services/data-manager/service/ical/icalFileGeneration.go delete mode 100644 services/data-manager/service/ical/icalFileGeneration_test.go delete mode 100644 services/data-manager/service/ical/icsComponenter.go diff --git a/services/data-manager/service/db/dbEvents.go b/services/data-manager/service/db/dbEvents.go index f6cf5a2..7c7c174 100644 --- a/services/data-manager/service/db/dbEvents.go +++ b/services/data-manager/service/db/dbEvents.go @@ -18,6 +18,7 @@ package db import ( "fmt" + "github.com/google/uuid" "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/tools/types" "htwkalender/data-manager/model" @@ -138,11 +139,11 @@ func buildIcalQueryForModules(modulesUuid []string) dbx.Expression { // following the pattern of only containing alphanumeric characters and dashes for _, moduleUuid := range modulesUuid { - if !IsSafeIdentifier(moduleUuid) { + err := uuid.Validate(moduleUuid) + if err != nil { slog.Warn("Module UUID is not safe: ", "moduleUuid", moduleUuid) return dbx.HashExp{} } - } // build where conditions for each module diff --git a/services/data-manager/service/db/dbEvents_test.go b/services/data-manager/service/db/dbEvents_test.go index 5941c58..8708394 100644 --- a/services/data-manager/service/db/dbEvents_test.go +++ b/services/data-manager/service/db/dbEvents_test.go @@ -38,13 +38,13 @@ func Test_buildIcalQueryForModules(t *testing.T) { }, { name: "one module", - args: args{modules: []string{"test"}}, - want: dbx.HashExp{"uuid": "test"}, + args: args{modules: []string{"77eddc32-c49d-5d0a-8c36-17b266396641"}}, + want: dbx.HashExp{"uuid": "77eddc32-c49d-5d0a-8c36-17b266396641"}, }, { name: "two modules", - args: args{modules: []string{"test", "test2"}}, - want: dbx.Or(dbx.HashExp{"uuid": "test"}, dbx.HashExp{"uuid": "test2"}), + args: args{modules: []string{"9e5081e6-4c56-57b9-9965-f6dc74559755", "48cd8c4e-fb70-595c-9dfb-7035f56326d9"}}, + want: dbx.Or(dbx.HashExp{"uuid": "9e5081e6-4c56-57b9-9965-f6dc74559755"}, dbx.HashExp{"uuid": "48cd8c4e-fb70-595c-9dfb-7035f56326d9"}), }, } for _, tt := range tests { diff --git a/services/data-manager/service/db/dbFunctions.go b/services/data-manager/service/db/dbFunctions.go index 3f6f2b6..05cd48b 100644 --- a/services/data-manager/service/db/dbFunctions.go +++ b/services/data-manager/service/db/dbFunctions.go @@ -19,26 +19,9 @@ package db import ( "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/models" - "log/slog" - "regexp" ) func FindCollection(app *pocketbase.PocketBase, collectionName string) (*models.Collection, error) { collection, dbError := app.Dao().FindCollectionByNameOrId(collectionName) return collection, dbError } - -// IsSafeIdentifier check uuids against sql injection -// uuids are generated by the system and are not user input -// following the pattern of only containing alphanumeric characters and dashes -func IsSafeIdentifier(uuid string) bool { - // Define a regular expression that matches only valid UUID characters (alphanumeric and dashes) - validUUIDPattern := `^[a-zA-Z0-9-]+$` - match, err := regexp.MatchString(validUUIDPattern, uuid) - if err != nil { - // Handle the error according to your application's needs - slog.Warn("Invalid UUID pattern", "uuid", uuid) - return false - } - return match -} diff --git a/services/data-manager/service/db/dbFunctions_test.go b/services/data-manager/service/db/dbFunctions_test.go deleted file mode 100644 index 2f1612f..0000000 --- a/services/data-manager/service/db/dbFunctions_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package db - -import "testing" - -func TestIsSafeIdentifier(t *testing.T) { - type args struct { - uuid string - } - tests := []struct { - name string - args args - want bool - }{ - { - name: "Test safe identifier", - args: args{ - uuid: "1234567890-1234567890-1234567890-1234567890", - }, - want: true, - }, - { - name: "Test safe identifier", - args: args{ - uuid: "1234567890-1234567890-1234567890-1234567890", - }, - want: true, - }, - { - name: "Test safe identifier", - args: args{ - uuid: "77eddc32-c49d-5d0a-8c36-17b266396641", - }, - want: true, - }, - { - name: "Test unsafe identifier", - args: args{ - uuid: "77eddc32-c49d-5d0a-8c36-17/1!!b266396641-", - }, - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := IsSafeIdentifier(tt.args.uuid); got != tt.want { - t.Errorf("IsSafeIdentifier() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/services/data-manager/service/fetch/v2/fetcher.go b/services/data-manager/service/fetch/v2/fetcher.go index f8af754..ed1e77a 100644 --- a/services/data-manager/service/fetch/v2/fetcher.go +++ b/services/data-manager/service/fetch/v2/fetcher.go @@ -195,6 +195,8 @@ func parseHTML(webpage string) (*html.Node, error) { return doc, nil } +// generateUUIDs generates a UUID for each event based on the event name, course and semester +// the UUID is used to identify the event in the database func generateUUIDs(events []model.Event) []model.Event { for i, event := range events { // generate a hash value from the event name, course and semester diff --git a/services/data-manager/service/ical/icalFileGeneration.go b/services/data-manager/service/ical/icalFileGeneration.go deleted file mode 100644 index b2ee39b..0000000 --- a/services/data-manager/service/ical/icalFileGeneration.go +++ /dev/null @@ -1,173 +0,0 @@ -//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format. -//Copyright (C) 2024 HTWKalender support@htwkalender.de - -//This program is free software: you can redistribute it and/or modify -//it under the terms of the GNU Affero General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//This program is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU Affero General Public License for more details. - -//You should have received a copy of the GNU Affero General Public License -//along with this program. If not, see . - -package ical - -import ( - "htwkalender/data-manager/model" - "htwkalender/data-manager/service/functions" - clock "htwkalender/data-manager/service/functions/time" - "htwkalender/data-manager/service/names" - "time" - - "github.com/jordic/goics" - _ "time/tzdata" -) - -// IcalModel local type for EmitICal function -type IcalModel struct { - Events model.Events - Mapping map[string]model.FeedCollection -} - -// EmitICal implements the interface for goics -func (icalModel IcalModel) EmitICal() goics.Componenter { - internalClock := clock.RealClock{} - c := generateIcalEmit(icalModel, internalClock) - return c -} - -func generateIcalEmit(icalModel IcalModel, internalClock clock.Clock) *goics.Component { - europeTime, _ := time.LoadLocation("Europe/Berlin") - c := goics.NewComponent() - c.SetType("VCALENDAR") - // PRODID is required by the standard - c.AddProperty("PRODID", "-//HTWK Kalender//htwkalender.de//DE") - - c.AddProperty("VERSION", "2.0") - c.AddProperty("CALSCALE", "GREGORIAN") - c.AddProperty("TZID", "EUROPE/BERLIN") - c.AddProperty("X-WR-CALNAME", "HTWK Kalender") - c.AddProperty("X-WR-TIMEZONE", "EUROPE/BERLIN") - //add v time zone - icalModel.vtimezone(c) - - for _, event := range icalModel.Events { - mapEntry, mappingFound := icalModel.Mapping[event.UUID] - - s := goics.NewComponent() - s.SetType("VEVENT") - - s.AddProperty(goics.FormatDateTime("DTSTAMP", internalClock.Now().Local().In(europeTime))) - - // create a unique id for the event by hashing the event start, end, course and name - var eventHash = functions.HashString(event.Start.String() + event.End.String() + event.Course + event.Name + event.Rooms) - - s.AddProperty("UID", eventHash+"@htwkalender.de") - s.AddProperty(goics.FormatDateTime("DTEND", event.End.Time().Local().In(europeTime))) - s.AddProperty(goics.FormatDateTime("DTSTART", event.Start.Time().Local().In(europeTime))) - - if mappingFound { - addPropertyIfNotEmpty(s, "SUMMARY", replaceNameIfUserDefined(&event, mapEntry)) - addAlarmIfSpecified(s, event, mapEntry, internalClock) - } else { - addPropertyIfNotEmpty(s, "SUMMARY", event.Name) - } - - addPropertyIfNotEmpty(s, "DESCRIPTION", generateDescription(event)) - addPropertyIfNotEmpty(s, "LOCATION", event.Rooms) - c.AddComponent(s) - } - return c -} - -func (icalModel IcalModel) vtimezone(c *goics.Component) { - tz := goics.NewComponent() - tz.SetType("VTIMEZONE") - tz.AddProperty("TZID", "EUROPE/BERLIN") - //add standard time - icalModel.standard(tz) - //add daylight time - icalModel.daylight(tz) - - c.AddComponent(tz) -} - -func (icalModel IcalModel) standard(tz *goics.Component) { - st := NewHtwkalenderComponent() - st.SetType("STANDARD") - st.AddProperty("DTSTART", "19701025T030000") - st.AddProperty("RRULE", "FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU") - st.AddProperty("TZOFFSETFROM", "+0200") - st.AddProperty("TZOFFSETTO", "+0100") - st.AddProperty("TZNAME", "CET") - tz.AddComponent(st) -} - -// create an override for goics component function Write -// to add the RRULE property - -func (icalModel IcalModel) daylight(tz *goics.Component) { - dt := NewHtwkalenderComponent() - dt.SetType("DAYLIGHT") - dt.AddProperty("DTSTART", "19700329T020000") - dt.AddProperty("TZOFFSETFROM", "+0100") - dt.AddProperty("TZOFFSETTO", "+0200") - dt.AddProperty("TZNAME", "CEST") - dt.AddProperty("RRULE", "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU") - tz.AddComponent(dt) -} - -// if reminder is specified in the configuration for this event, an alarm will be added to the event -func addAlarmIfSpecified(s *goics.Component, event model.Event, mapping model.FeedCollection, clock clock.Clock) { - // if event.Start > now - // then add alarm - if event.Start.Time().Local().After(clock.Now().Local()) && mapping.Reminder { - a := goics.NewComponent() - a.SetType("VALARM") - a.AddProperty("TRIGGER", "-P0DT0H15M0S") - a.AddProperty("ACTION", "DISPLAY") - a.AddProperty("DESCRIPTION", "Next course: "+replaceNameIfUserDefined(&event, mapping)+" in "+event.Rooms) - s.AddComponent(a) - } -} - -// replaceNameIfUserDefined replaces the name of the event with the user defined name if it is not empty -// all contained template strings will be replaced with the corresponding values from the event -func replaceNameIfUserDefined(event *model.Event, mapping model.FeedCollection) string { - if !functions.OnlyWhitespace(mapping.UserDefinedName) { - return names.ReplaceTemplateSubStrings(mapping.UserDefinedName, *event) - } - - return event.Name -} - -// AddPropertyIfNotEmpty adds a property to the component if the value is not empty -// or contains only whitespaces -func addPropertyIfNotEmpty(component *goics.Component, key string, value string) { - if !functions.OnlyWhitespace(value) { - component.AddProperty(key, value) - } -} - -func generateDescription(event model.Event) string { - var description string - - if !functions.OnlyWhitespace(event.Prof) { - description += "Profs: " + event.Prof + "\n" - } - if !functions.OnlyWhitespace(event.Course) { - description += "Gruppen: " + event.Course + "\n" - } - if !functions.OnlyWhitespace(event.EventType) { - description += "Typ: " + event.EventType + event.Compulsory + "\n" - } - if !functions.OnlyWhitespace(event.Notes) { - description += "Notizen: " + event.Notes + "\n" - } - - return description -} diff --git a/services/data-manager/service/ical/icalFileGeneration_test.go b/services/data-manager/service/ical/icalFileGeneration_test.go deleted file mode 100644 index 383a387..0000000 --- a/services/data-manager/service/ical/icalFileGeneration_test.go +++ /dev/null @@ -1,258 +0,0 @@ -//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format. -//Copyright (C) 2024 HTWKalender support@htwkalender.de - -//This program is free software: you can redistribute it and/or modify -//it under the terms of the GNU Affero General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//This program is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU Affero General Public License for more details. - -//You should have received a copy of the GNU Affero General Public License -//along with this program. If not, see . - -package ical - -import ( - "github.com/jordic/goics" - "htwkalender/data-manager/model" - mockTime "htwkalender/data-manager/service/functions/time" - "reflect" - "testing" - "time" -) - -func TestIcalModel_EmitICal(t *testing.T) { - type fields struct { - Events model.Events - Mapping map[string]model.FeedCollection - } - tests := []struct { - name string - fields fields - want *goics.Component - }{ - { - name: "Test EmitICal", - fields: fields{ - Events: model.Events{ - { - UUID: "123", - Name: "Test", - EventType: "Test", - Notes: "Test", - Prof: "Test", - Rooms: "Test", - BookedAt: "Test", - }, - }, - Mapping: map[string]model.FeedCollection{ - "123": { - UUID: "123", - Name: "Test", - Course: "Test", - UserDefinedName: "Test", - }, - }, - }, - want: &goics.Component{ - Tipo: "VCALENDAR", - Elements: []goics.Componenter{ - &goics.Component{ - Tipo: "VTIMEZONE", - Elements: []goics.Componenter{ - &HtwkalenderComponent{ - Component: &goics.Component{ - Tipo: "STANDARD", - Elements: []goics.Componenter{}, - Properties: map[string][]string{ - "DTSTART": {"19701025T030000"}, - "RRULE": {"FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU"}, - "TZOFFSETFROM": {"+0200"}, - "TZOFFSETTO": {"+0100"}, - "TZNAME": {"CET"}, - }, - }, - }, - &HtwkalenderComponent{ - Component: &goics.Component{ - Tipo: "DAYLIGHT", - Elements: []goics.Componenter{}, - Properties: map[string][]string{ - "DTSTART": {"19700329T020000"}, - "TZOFFSETFROM": {"+0100"}, - "TZOFFSETTO": {"+0200"}, - "TZNAME": {"CEST"}, - "RRULE": {"FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU"}, - }, - }, - }, - }, - Properties: map[string][]string{ - "TZID": {"EUROPE/BERLIN"}, - }, - }, - &goics.Component{ - Tipo: "VEVENT", - Elements: []goics.Componenter{}, - Properties: map[string][]string{ - "DTSTAMP": {"20231201T000000Z"}, - "UID": {"a8d627d93f518e9096b6f40e36d27b7660fa26d318ef1adc43da750e49ebe4be@htwkalender.de"}, - "DTEND": {"00010101T000000Z"}, - "DTSTART": {"00010101T000000Z"}, - "SUMMARY": {"Test"}, - "DESCRIPTION": {"Profs: Test\nTyp: Test\nNotizen: Test\n"}, - "LOCATION": {"Test"}, - }, - }, - }, - Properties: map[string][]string{ - "PRODID": {"-//HTWK Kalender//htwkalender.de//DE"}, - "VERSION": {"2.0"}, - "CALSCALE": {"GREGORIAN"}, - "TZID": {"EUROPE/BERLIN"}, - "X-WR-CALNAME": {"HTWK Kalender"}, - "X-WR-TIMEZONE": {"EUROPE/BERLIN"}, - }, - }, - }, - { - name: "Test Similar Events like Sport Courses", - fields: fields{ - Events: model.Events{ - { - UUID: "123", - Name: "Test", - Course: "Test", - EventType: "Test", - Notes: "Test", - Prof: "Test", - Rooms: "ZU430", - BookedAt: "Test", - Start: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC)), - End: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 1, 0, 0, 0, time.UTC)), - }, - { - UUID: "123", - Name: "Test", - Course: "Test", - EventType: "Test", - Notes: "Test", - Prof: "Test", - Rooms: "ZU221", - BookedAt: "Test", - Start: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC)), - End: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 1, 0, 0, 0, time.UTC)), - }, - }, - Mapping: map[string]model.FeedCollection{ - "123": { - UUID: "123", - Name: "Test", - Course: "Test", - UserDefinedName: "UserDefinedName", - }, - }, - }, - want: &goics.Component{ - Tipo: "VCALENDAR", - Elements: []goics.Componenter{ - &goics.Component{ - Tipo: "VTIMEZONE", - Elements: []goics.Componenter{ - &HtwkalenderComponent{ - Component: &goics.Component{ - Tipo: "STANDARD", - Elements: []goics.Componenter{}, - Properties: map[string][]string{ - "DTSTART": {"19701025T030000"}, - "RRULE": {"FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU"}, - "TZOFFSETFROM": {"+0200"}, - "TZOFFSETTO": {"+0100"}, - "TZNAME": {"CET"}, - }, - }, - }, - &HtwkalenderComponent{ - Component: &goics.Component{ - Tipo: "DAYLIGHT", - Elements: []goics.Componenter{}, - Properties: map[string][]string{ - "DTSTART": {"19700329T020000"}, - "TZOFFSETFROM": {"+0100"}, - "TZOFFSETTO": {"+0200"}, - "TZNAME": {"CEST"}, - "RRULE": {"FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU"}, - }, - }, - }, - }, - Properties: map[string][]string{ - "TZID": {"EUROPE/BERLIN"}, - }, - }, - &goics.Component{ - Tipo: "VEVENT", - Elements: []goics.Componenter{}, - Properties: map[string][]string{ - "DTSTAMP": {"20231201T000000Z"}, - "UID": {"b52a7a081f46eeba9b402114493278a34a48b572c84e53d7ac4da9dea15cdff2@htwkalender.de"}, - "DTEND": {"20231201T010000Z"}, - "DTSTART": {"20231201T000000Z"}, - "SUMMARY": {"UserDefinedName"}, - "DESCRIPTION": {"Profs: Test\nGruppen: Test\nTyp: Test\nNotizen: Test\n"}, - "LOCATION": {"ZU430"}, - }, - }, - &goics.Component{ - Tipo: "VEVENT", - Elements: []goics.Componenter{}, - Properties: map[string][]string{ - "DTSTAMP": {"20231201T000000Z"}, - "UID": {"5e946c0c4474bc6e6337262093e3ef31477e026bbc6bab398d755b002506d9d7@htwkalender.de"}, - "DTEND": {"20231201T010000Z"}, - "DTSTART": {"20231201T000000Z"}, - "SUMMARY": {"UserDefinedName"}, - "DESCRIPTION": {"Profs: Test\nGruppen: Test\nTyp: Test\nNotizen: Test\n"}, - "LOCATION": {"ZU221"}, - }, - }, - }, - Properties: map[string][]string{ - "PRODID": {"-//HTWK Kalender//htwkalender.de//DE"}, - "VERSION": {"2.0"}, - "CALSCALE": {"GREGORIAN"}, - "TZID": {"EUROPE/BERLIN"}, - "X-WR-CALNAME": {"HTWK Kalender"}, - "X-WR-TIMEZONE": {"EUROPE/BERLIN"}, - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - icalModel := IcalModel{ - Events: tt.fields.Events, - Mapping: tt.fields.Mapping, - } - - mockClock := mockTime.MockClock{ - NowTime: time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC), - } - - if got := generateIcalEmit(icalModel, mockClock); !reflect.DeepEqual(got, tt.want) { - t.Errorf("EmitICal() = \n%v, want \n%v", got, tt.want) - - // Print the differences - for i, element := range got.Elements { - if !reflect.DeepEqual(element, tt.want.Elements[i]) { - t.Errorf("Element %d: got \n%v, want \n%v", i, element, tt.want.Elements[i]) - } - } - } - }) - } -} diff --git a/services/data-manager/service/ical/icsComponenter.go b/services/data-manager/service/ical/icsComponenter.go deleted file mode 100644 index b8c3deb..0000000 --- a/services/data-manager/service/ical/icsComponenter.go +++ /dev/null @@ -1,62 +0,0 @@ -//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format. -//Copyright (C) 2024 HTWKalender support@htwkalender.de - -//This program is free software: you can redistribute it and/or modify -//it under the terms of the GNU Affero General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//This program is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU Affero General Public License for more details. - -//You should have received a copy of the GNU Affero General Public License -//along with this program. If not, see . - -package ical - -import ( - "github.com/jordic/goics" - "sort" - "strings" -) - -type HtwkalenderComponent struct { - *goics.Component -} - -func NewHtwkalenderComponent() *HtwkalenderComponent { - return &HtwkalenderComponent{ - Component: goics.NewComponent(), - } -} - -// Writes the component to the Writer -func (c *HtwkalenderComponent) Write(w *goics.ICalEncode) { - w.WriteLine("BEGIN:" + c.Tipo + goics.CRLF) - - // Iterate over component properties - var keys []string - for k := range c.Properties { - keys = append(keys, k) - } - sort.Strings(keys) - for _, key := range keys { - vals := c.Properties[key] - for _, val := range vals { - w.WriteLine(WriteStringField(key, val)) - } - } - - for _, xc := range c.Elements { - xc.Write(w) - } - - w.WriteLine("END:" + c.Tipo + goics.CRLF) -} - -// WriteStringField UID:asdfasdfаs@dfasdf.com -func WriteStringField(key string, val string) string { - return strings.ToUpper(key) + ":" + (val) + goics.CRLF -} From acc048a80af42492be9eff810902bc26b206b70b Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Tue, 18 Jun 2024 23:46:23 +0200 Subject: [PATCH 11/18] feat:#36 updated feed service with more protobuf endpoints --- services/Makefile | 2 +- services/data-manager/service/db/dbFeeds.go | 2 +- .../data-manager/service/grpc/feedService.go | 33 +++++++++ services/data-manager/service/grpc/mapper.go | 10 +++ .../service/grpc/moduleService.go | 69 ++++++++++++++++++ services/data-manager/service/grpc/server.go | 71 ++----------------- services/ical/model/icalModel.go | 2 - services/ical/service/connector/grpc/feeds.go | 52 ++++++++++++++ services/ical/service/ical/ical.go | 2 +- services/protobuf/feeds.proto | 23 ++++++ 10 files changed, 197 insertions(+), 69 deletions(-) create mode 100644 services/data-manager/service/grpc/feedService.go create mode 100644 services/data-manager/service/grpc/moduleService.go create mode 100644 services/ical/service/connector/grpc/feeds.go create mode 100644 services/protobuf/feeds.proto diff --git a/services/Makefile b/services/Makefile index 94269fa..1cf2ba8 100644 --- a/services/Makefile +++ b/services/Makefile @@ -9,7 +9,7 @@ build-ical: gen: @protoc \ - --proto_path=protobuf "protobuf/modules.proto" \ + --proto_path=protobuf "protobuf/*" \ --go_out="common/genproto/modules" \ --go_opt=paths=source_relative \ --go-grpc_out="common/genproto/modules" \ diff --git a/services/data-manager/service/db/dbFeeds.go b/services/data-manager/service/db/dbFeeds.go index 1ad6ad3..2ae46e1 100644 --- a/services/data-manager/service/db/dbFeeds.go +++ b/services/data-manager/service/db/dbFeeds.go @@ -37,7 +37,7 @@ func SaveFeed(feed model.Feed, collection *models.Collection, app *pocketbase.Po return record, nil } -func FindFeedByToken(token string, app *pocketbase.PocketBase) (*model.Feed, error) { +func FindFeedByToken(app *pocketbase.PocketBase, token string) (*model.Feed, error) { record, err := app.Dao().FindRecordById("feeds", token) diff --git a/services/data-manager/service/grpc/feedService.go b/services/data-manager/service/grpc/feedService.go new file mode 100644 index 0000000..67870c8 --- /dev/null +++ b/services/data-manager/service/grpc/feedService.go @@ -0,0 +1,33 @@ +package grpc + +import ( + "context" + "github.com/pocketbase/pocketbase" + pb "htwkalender/common/genproto/modules" + "htwkalender/data-manager/service/db" +) + +type FeedServiceHandler struct { + app *pocketbase.PocketBase + pb.UnimplementedFeedServiceServer +} + +func (s *FeedServiceHandler) GetFeed(ctx context.Context, in *pb.GetFeedRequest) (*pb.GetFeedResponse, error) { + + s.app.Logger().Info( + "Protobuf - GetFeed", + "uuid", in.Id, + ) + + // get feed from database by UUID + feed, err := db.FindFeedByToken(s.app, in.Id) + if err != nil { + return nil, err + } + + // Implement your logic here to fetch feed data based on the UUID + // Example response + return &pb.GetFeedResponse{ + Feed: feedToProto(feed), + }, nil +} diff --git a/services/data-manager/service/grpc/mapper.go b/services/data-manager/service/grpc/mapper.go index 01f439c..ee3ea58 100644 --- a/services/data-manager/service/grpc/mapper.go +++ b/services/data-manager/service/grpc/mapper.go @@ -31,3 +31,13 @@ func eventsToProto(events model.Events) []*pb.Event { } return protoEvents } + +func feedToProto(feed *model.Feed) *pb.Feed { + return &pb.Feed{ + Id: feed.Id, + Created: feed.Created.String(), + Updated: feed.Updated.String(), + Retrieved: feed.Retrieved.String(), + Modules: feed.Modules, + } +} diff --git a/services/data-manager/service/grpc/moduleService.go b/services/data-manager/service/grpc/moduleService.go new file mode 100644 index 0000000..b220809 --- /dev/null +++ b/services/data-manager/service/grpc/moduleService.go @@ -0,0 +1,69 @@ +package grpc + +import ( + "context" + "github.com/pocketbase/pocketbase" + pb "htwkalender/common/genproto/modules" + "htwkalender/data-manager/service/db" +) + +type ModuleServiceHandler struct { + app *pocketbase.PocketBase + pb.UnimplementedModuleServiceServer +} + +func (s *ModuleServiceHandler) GetModule(ctx context.Context, in *pb.GetModuleRequest) (*pb.GetModuleResponse, error) { + + s.app.Logger().Info( + "Protobuf - GetModule", + "uuid", in.Uuid, + ) + + // get module from database by UUID + module, err := db.FindModuleByUUID(s.app, in.Uuid) + if err != nil { + return nil, err + } + + events, err := db.FindAllEventsByModule(s.app, module) + if err != nil { + return nil, err + } + + //map module Events to proto struct Events + protoEvents := make([]*pb.Event, 0) + for _, event := range events { + protoEvents = append(protoEvents, eventToProto(&event)) + } + //map module to proto struct + protoModule := &pb.Module{ + Uuid: module.UUID, + Name: module.Name, + Prof: module.Prof, + Course: module.Course, + Semester: module.Semester, + Events: protoEvents, + } + // Implement your logic here to fetch module data based on the UUID + // Example response + return &pb.GetModuleResponse{ + Module: protoModule, + }, nil +} + +func (s *ModuleServiceHandler) GetEventsForModules(ctx context.Context, in *pb.GetModulesRequest) (*pb.GetEventsResponse, error) { + + s.app.Logger().Info( + "Protobuf - GetEventsForModules", + "uuids", in.Uuids, + ) + + events, err := db.GetPlanForModules(s.app, in.Uuids) + if err != nil { + return nil, err + } + + return &pb.GetEventsResponse{ + Events: eventsToProto(events), + }, nil +} diff --git a/services/data-manager/service/grpc/server.go b/services/data-manager/service/grpc/server.go index edf3191..f5b6ad3 100644 --- a/services/data-manager/service/grpc/server.go +++ b/services/data-manager/service/grpc/server.go @@ -1,9 +1,7 @@ package grpc import ( - "context" "github.com/pocketbase/pocketbase" - "htwkalender/data-manager/service/db" "log" "net" @@ -11,78 +9,23 @@ import ( pb "htwkalender/common/genproto/modules" ) -type ModulesGrpcHandler struct { - app *pocketbase.PocketBase - pb.UnimplementedModuleServiceServer -} - -func (s *ModulesGrpcHandler) GetModule(ctx context.Context, in *pb.GetModuleRequest) (*pb.GetModuleResponse, error) { - - s.app.Logger().Info( - "Protobuf - GetModule", - "uuid", in.Uuid, - ) - - // get module from database by UUID - module, err := db.FindModuleByUUID(s.app, in.Uuid) - if err != nil { - return nil, err - } - - events, err := db.FindAllEventsByModule(s.app, module) - if err != nil { - return nil, err - } - - //map module Events to proto struct Events - protoEvents := make([]*pb.Event, 0) - for _, event := range events { - protoEvents = append(protoEvents, eventToProto(&event)) - } - //map module to proto struct - protoModule := &pb.Module{ - Uuid: module.UUID, - Name: module.Name, - Prof: module.Prof, - Course: module.Course, - Semester: module.Semester, - Events: protoEvents, - } - // Implement your logic here to fetch module data based on the UUID - // Example response - return &pb.GetModuleResponse{ - Module: protoModule, - }, nil -} - func StartGRPCServer(app *pocketbase.PocketBase) { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterModuleServiceServer(s, &ModulesGrpcHandler{ + + pb.RegisterModuleServiceServer(s, &ModuleServiceHandler{ app: app, }) + + pb.RegisterFeedServiceServer(s, &FeedServiceHandler{ + app: app, + }) + log.Printf("server listening at %v", lis.Addr()) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } - -func (s *ModulesGrpcHandler) GetEventsForModules(ctx context.Context, in *pb.GetModulesRequest) (*pb.GetEventsResponse, error) { - - s.app.Logger().Info( - "Protobuf - GetEventsForModules", - "uuids", in.Uuids, - ) - - events, err := db.GetPlanForModules(s.app, in.Uuids) - if err != nil { - return nil, err - } - - return &pb.GetEventsResponse{ - Events: eventsToProto(events), - }, nil -} diff --git a/services/ical/model/icalModel.go b/services/ical/model/icalModel.go index cbd11bf..7ff9263 100644 --- a/services/ical/model/icalModel.go +++ b/services/ical/model/icalModel.go @@ -19,7 +19,6 @@ package model import ( "encoding/json" "fmt" - "log/slog" "strings" "time" ) @@ -88,7 +87,6 @@ func (jt *JSONTime) UnmarshalJSON(b []byte) error { func ToJSONTime(timeString string) JSONTime { t, err := time.Parse(DefaultDateLayout, timeString) if err != nil { - slog.Error("error parsing time string: ", "error", err) return JSONTime(time.Time{}) } return JSONTime(t) diff --git a/services/ical/service/connector/grpc/feeds.go b/services/ical/service/connector/grpc/feeds.go new file mode 100644 index 0000000..0f1f082 --- /dev/null +++ b/services/ical/service/connector/grpc/feeds.go @@ -0,0 +1,52 @@ +package grpc + +import ( + "context" + "github.com/goccy/go-json" + "google.golang.org/grpc" + pb "htwkalender/common/genproto/modules" + "htwkalender/ical/model" + "log/slog" + "time" +) + +func GetFeed(feedId string, conn *grpc.ClientConn) (model.FeedRecord, error) { + c := pb.NewFeedServiceClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + r, err := c.GetFeed(ctx, &pb.GetFeedRequest{Id: feedId}) + if err != nil { + slog.Error("could not get modules: %v", "error", err) + return model.FeedRecord{}, err + } + + feed, err := protoToFeed(r.GetFeed()) + if err != nil { + slog.Error("could not convert feed: %v", "error", err) + return model.FeedRecord{}, err + } + + return feed, nil +} + +func protoToFeed(feed *pb.Feed) (model.FeedRecord, error) { + + // unmarshal the []model.FeedModule from json + var modules []model.FeedModule + err := json.Unmarshal([]byte(feed.Modules), &modules) + if err != nil { + slog.Error("could not unmarshal modules: %v", "error", err) + return model.FeedRecord{}, err + } + + return model.FeedRecord{ + BaseModel: model.BaseModel{ + Id: feed.Id, + Created: model.ToJSONTime(feed.Created), + Updated: model.ToJSONTime(feed.Updated), + }, + Retrieved: model.ToJSONTime(feed.Retrieved), + Modules: modules, + }, nil +} diff --git a/services/ical/service/ical/ical.go b/services/ical/service/ical/ical.go index be57533..baa6160 100644 --- a/services/ical/service/ical/ical.go +++ b/services/ical/service/ical/ical.go @@ -14,7 +14,7 @@ const expirationTime = 5 * time.Minute func Feed(app model.AppType, token string) (string, error) { // get feed by token - feed, err := connector.GetFeedByToken(app.DataManagerURL, token) + feed, err := htwkalenderGrpc.GetFeed(token, app.GrpcClient) if err != nil { return "", err } diff --git a/services/protobuf/feeds.proto b/services/protobuf/feeds.proto new file mode 100644 index 0000000..7580cbd --- /dev/null +++ b/services/protobuf/feeds.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +option go_package = "htwkalender/common/modules"; + +service FeedService { + rpc GetFeed(GetFeedRequest) returns (GetFeedResponse) {} +} + +message Feed { + string id = 1; + string modules = 2; + string retrieved = 3; + string created = 4; + string updated = 5; +} + +message GetFeedRequest { + string id = 1; +} + +message GetFeedResponse { + Feed feed = 1; +} \ No newline at end of file From 2ec1777f7bf0943a6cd96736189660c668c16cb6 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Tue, 18 Jun 2024 23:46:28 +0200 Subject: [PATCH 12/18] feat:#36 updated feed service with more protobuf endpoints --- services/common/genproto/modules/feeds.pb.go | 312 ++++++++++++++++++ .../common/genproto/modules/feeds_grpc.pb.go | 105 ++++++ 2 files changed, 417 insertions(+) create mode 100644 services/common/genproto/modules/feeds.pb.go create mode 100644 services/common/genproto/modules/feeds_grpc.pb.go diff --git a/services/common/genproto/modules/feeds.pb.go b/services/common/genproto/modules/feeds.pb.go new file mode 100644 index 0000000..97aaa32 --- /dev/null +++ b/services/common/genproto/modules/feeds.pb.go @@ -0,0 +1,312 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v5.27.1 +// source: feeds.proto + +package modules + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Feed struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Modules string `protobuf:"bytes,2,opt,name=modules,proto3" json:"modules,omitempty"` + Retrieved string `protobuf:"bytes,3,opt,name=retrieved,proto3" json:"retrieved,omitempty"` + Created string `protobuf:"bytes,4,opt,name=created,proto3" json:"created,omitempty"` + Updated string `protobuf:"bytes,5,opt,name=updated,proto3" json:"updated,omitempty"` +} + +func (x *Feed) Reset() { + *x = Feed{} + if protoimpl.UnsafeEnabled { + mi := &file_feeds_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Feed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Feed) ProtoMessage() {} + +func (x *Feed) ProtoReflect() protoreflect.Message { + mi := &file_feeds_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Feed.ProtoReflect.Descriptor instead. +func (*Feed) Descriptor() ([]byte, []int) { + return file_feeds_proto_rawDescGZIP(), []int{0} +} + +func (x *Feed) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Feed) GetModules() string { + if x != nil { + return x.Modules + } + return "" +} + +func (x *Feed) GetRetrieved() string { + if x != nil { + return x.Retrieved + } + return "" +} + +func (x *Feed) GetCreated() string { + if x != nil { + return x.Created + } + return "" +} + +func (x *Feed) GetUpdated() string { + if x != nil { + return x.Updated + } + return "" +} + +type GetFeedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetFeedRequest) Reset() { + *x = GetFeedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_feeds_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFeedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFeedRequest) ProtoMessage() {} + +func (x *GetFeedRequest) ProtoReflect() protoreflect.Message { + mi := &file_feeds_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFeedRequest.ProtoReflect.Descriptor instead. +func (*GetFeedRequest) Descriptor() ([]byte, []int) { + return file_feeds_proto_rawDescGZIP(), []int{1} +} + +func (x *GetFeedRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetFeedResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Feed *Feed `protobuf:"bytes,1,opt,name=feed,proto3" json:"feed,omitempty"` +} + +func (x *GetFeedResponse) Reset() { + *x = GetFeedResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_feeds_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFeedResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFeedResponse) ProtoMessage() {} + +func (x *GetFeedResponse) ProtoReflect() protoreflect.Message { + mi := &file_feeds_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFeedResponse.ProtoReflect.Descriptor instead. +func (*GetFeedResponse) Descriptor() ([]byte, []int) { + return file_feeds_proto_rawDescGZIP(), []int{2} +} + +func (x *GetFeedResponse) GetFeed() *Feed { + if x != nil { + return x.Feed + } + return nil +} + +var File_feeds_proto protoreflect.FileDescriptor + +var file_feeds_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x01, + 0x0a, 0x04, 0x46, 0x65, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, + 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x2c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x04, 0x66, 0x65, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x52, 0x04, 0x66, 0x65, + 0x65, 0x64, 0x32, 0x3d, 0x0a, 0x0b, 0x46, 0x65, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x12, 0x0f, 0x2e, 0x47, + 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, + 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0x1c, 0x5a, 0x1a, 0x68, 0x74, 0x77, 0x6b, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_feeds_proto_rawDescOnce sync.Once + file_feeds_proto_rawDescData = file_feeds_proto_rawDesc +) + +func file_feeds_proto_rawDescGZIP() []byte { + file_feeds_proto_rawDescOnce.Do(func() { + file_feeds_proto_rawDescData = protoimpl.X.CompressGZIP(file_feeds_proto_rawDescData) + }) + return file_feeds_proto_rawDescData +} + +var file_feeds_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_feeds_proto_goTypes = []interface{}{ + (*Feed)(nil), // 0: Feed + (*GetFeedRequest)(nil), // 1: GetFeedRequest + (*GetFeedResponse)(nil), // 2: GetFeedResponse +} +var file_feeds_proto_depIdxs = []int32{ + 0, // 0: GetFeedResponse.feed:type_name -> Feed + 1, // 1: FeedService.GetFeed:input_type -> GetFeedRequest + 2, // 2: FeedService.GetFeed:output_type -> GetFeedResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_feeds_proto_init() } +func file_feeds_proto_init() { + if File_feeds_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_feeds_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Feed); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_feeds_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFeedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_feeds_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFeedResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_feeds_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_feeds_proto_goTypes, + DependencyIndexes: file_feeds_proto_depIdxs, + MessageInfos: file_feeds_proto_msgTypes, + }.Build() + File_feeds_proto = out.File + file_feeds_proto_rawDesc = nil + file_feeds_proto_goTypes = nil + file_feeds_proto_depIdxs = nil +} diff --git a/services/common/genproto/modules/feeds_grpc.pb.go b/services/common/genproto/modules/feeds_grpc.pb.go new file mode 100644 index 0000000..10d1fc2 --- /dev/null +++ b/services/common/genproto/modules/feeds_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v5.27.1 +// source: feeds.proto + +package modules + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// FeedServiceClient is the client API for FeedService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type FeedServiceClient interface { + GetFeed(ctx context.Context, in *GetFeedRequest, opts ...grpc.CallOption) (*GetFeedResponse, error) +} + +type feedServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewFeedServiceClient(cc grpc.ClientConnInterface) FeedServiceClient { + return &feedServiceClient{cc} +} + +func (c *feedServiceClient) GetFeed(ctx context.Context, in *GetFeedRequest, opts ...grpc.CallOption) (*GetFeedResponse, error) { + out := new(GetFeedResponse) + err := c.cc.Invoke(ctx, "/FeedService/GetFeed", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// FeedServiceServer is the server API for FeedService service. +// All implementations must embed UnimplementedFeedServiceServer +// for forward compatibility +type FeedServiceServer interface { + GetFeed(context.Context, *GetFeedRequest) (*GetFeedResponse, error) + mustEmbedUnimplementedFeedServiceServer() +} + +// UnimplementedFeedServiceServer must be embedded to have forward compatible implementations. +type UnimplementedFeedServiceServer struct { +} + +func (UnimplementedFeedServiceServer) GetFeed(context.Context, *GetFeedRequest) (*GetFeedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetFeed not implemented") +} +func (UnimplementedFeedServiceServer) mustEmbedUnimplementedFeedServiceServer() {} + +// UnsafeFeedServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to FeedServiceServer will +// result in compilation errors. +type UnsafeFeedServiceServer interface { + mustEmbedUnimplementedFeedServiceServer() +} + +func RegisterFeedServiceServer(s grpc.ServiceRegistrar, srv FeedServiceServer) { + s.RegisterService(&FeedService_ServiceDesc, srv) +} + +func _FeedService_GetFeed_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetFeedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FeedServiceServer).GetFeed(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/FeedService/GetFeed", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FeedServiceServer).GetFeed(ctx, req.(*GetFeedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// FeedService_ServiceDesc is the grpc.ServiceDesc for FeedService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var FeedService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "FeedService", + HandlerType: (*FeedServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetFeed", + Handler: _FeedService_GetFeed_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "feeds.proto", +} From 0c9e4ec90db67f491a62b150f4dff05ec22c5403 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Wed, 19 Jun 2024 00:27:23 +0200 Subject: [PATCH 13/18] feat:#36 fixed pipeline context --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 87f07e3..49ca5e0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -178,7 +178,7 @@ build-data-manager-image: before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - - docker build --pull -t $IMAGE_TAG -f ./services/data-manager/Dockerfile --target prod ./services/data-manager + - docker build --pull -t $IMAGE_TAG -f ./services/data-manager/Dockerfile --target prod ./services - docker push $IMAGE_TAG rules: - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "development" @@ -201,7 +201,7 @@ build-ical-image: before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - - docker build --pull -t $IMAGE_TAG -f ./services/ical/Dockerfile --target prod ./services/ical + - docker build --pull -t $IMAGE_TAG -f ./services/ical/Dockerfile --target prod ./services - docker push $IMAGE_TAG rules: - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "development" From 7b9dd0ed506ca4b6c4fd93fd38ffc41aae08e57e Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Wed, 19 Jun 2024 01:06:30 +0200 Subject: [PATCH 14/18] feat:#36 fixed Dockerfile Entrypoint --- services/data-manager/Dockerfile | 2 +- services/ical/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/data-manager/Dockerfile b/services/data-manager/Dockerfile index 7bb6a3f..f1bcae8 100644 --- a/services/data-manager/Dockerfile +++ b/services/data-manager/Dockerfile @@ -17,7 +17,7 @@ # build stage FROM golang:alpine AS build -WORKDIR /app +WORKDIR /htwkalender-data-manager RUN apk add --no-cache --update go gcc g++ # Copy the source from the current directory to the Working Directory inside the container diff --git a/services/ical/Dockerfile b/services/ical/Dockerfile index d87835a..19d231c 100644 --- a/services/ical/Dockerfile +++ b/services/ical/Dockerfile @@ -17,7 +17,7 @@ # build stage FROM golang:alpine AS build -WORKDIR /app +WORKDIR /htwkalender-ical RUN apk add --no-cache --update go gcc g++ # Copy the source from the current directory to the Working Directory inside the container From e264b09f5982845dc89d1f299686f0baa2cf7166 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Wed, 19 Jun 2024 01:30:25 +0200 Subject: [PATCH 15/18] fix:#36 added env to prod and dev --- docker-compose.dev.yml | 2 ++ docker-compose.prod.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 26fdc84..719de55 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -29,6 +29,8 @@ services: image: DOCKER_REGISTRY_REPO-ical # DOCKER_REGISTRY_REPO will be replaced by CI pull_policy: always restart: always + environment: + - DATA_MANAGER_URL=htwkalender-data-manager networks: - "net" diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 8358f31..f52e1aa 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -29,6 +29,8 @@ services: image: DOCKER_REGISTRY_REPO-ical # DOCKER_REGISTRY_REPO will be replaced by CI pull_policy: always restart: always + environment: + - DATA_MANAGER_URL=htwkalender-data-manager networks: - "net" From 8124d84efda03ec5541ce20dfa559e853995366d Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Wed, 19 Jun 2024 20:43:59 +0200 Subject: [PATCH 16/18] feat:#36 added limit to proxy for POST --- reverseproxy.local.conf | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/reverseproxy.local.conf b/reverseproxy.local.conf index 8846d6d..6d57290 100644 --- a/reverseproxy.local.conf +++ b/reverseproxy.local.conf @@ -57,6 +57,31 @@ http { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; + geo $admin { + default 1; + #10.0.0.0/8 0; # Private Network + #127.0.0.0/8 0; # Localhost Network + #192.168.0.0/16 0; # Localhost Network + #141.57.0.0/16 0; # HTWK Leipzig Network + #172.16.0.0/12 0; # Private Network + } + + map $admin $limit_key { + 0 ''; + 1 $binary_remote_addr; + } + + map $request_method $ratelimit_key { + POST $binary_remote_addr; + default $binary_remote_addr; + } + + limit_req_zone $ratelimit_key zone=createFeed:10m rate=1r/s; + #limit_req_zone $limit_key zone=createFeed:10m rate=1r/m; + # Limit the number of requests per IP + limit_req_zone $limit_key zone=feed:20m rate=20r/m; + limit_req_zone $limit_key zone=modules:10m rate=30r/m; + server { listen 80; @@ -70,6 +95,7 @@ http { proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s; + limit_req zone=createFeed nodelay; } location /api { From a4a38a94f9747258068be6d55c83eaf323826e95 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Wed, 19 Jun 2024 22:03:15 +0200 Subject: [PATCH 17/18] fix:#36 updated ratelimit nginx for post feeds --- reverseproxy.conf | 11 ++++-- reverseproxy.dev.conf | 17 ++++------ reverseproxy.local.conf | 75 +++-------------------------------------- 3 files changed, 20 insertions(+), 83 deletions(-) diff --git a/reverseproxy.conf b/reverseproxy.conf index 86eb2dd..ebb7945 100644 --- a/reverseproxy.conf +++ b/reverseproxy.conf @@ -114,9 +114,15 @@ http { 1 $binary_remote_addr; } + # Different rate limits for different request methods + map $request_method $ratelimit_key { + POST $binary_remote_addr; + default ""; + } + + limit_req_zone $ratelimit_key zone=createFeed:10m rate=1r/m; # Limit the number of requests per IP limit_req_zone $limit_key zone=feed:20m rate=20r/m; - limit_req_zone $limit_key zone=createFeed:10m rate=1r/m; limit_req_zone $limit_key zone=modules:10m rate=30r/m; server { @@ -126,13 +132,14 @@ http { server_name cal.htwk-leipzig.de; location /api/feed { + limit_req zone=createFeed nodelay; + limit_req zone=feed burst=10 nodelay; proxy_pass http://htwkalender-ical:8091; client_max_body_size 2m; proxy_connect_timeout 600s; proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s; - limit_req zone=$limit_zone burst=10 nodelay; limit_req_status 429; } diff --git a/reverseproxy.dev.conf b/reverseproxy.dev.conf index ed8a7de..31656bc 100644 --- a/reverseproxy.dev.conf +++ b/reverseproxy.dev.conf @@ -116,20 +116,15 @@ http { } # Different rate limits for different request methods - map $request_method $limit_feed { - POST ''; # Create feed is limited to 1 request per minute - default $binary_remote_addr; # All other requests are limited to 20 requests per minute + map $request_method $ratelimit_key { + POST $binary_remote_addr; + default ""; } - - map $request_method $limit_createFeed { - POST $binary_remote_addr; # Create feed is limited to 1 request per minute - default ''; # All other requests are limited to 20 requests per minute - } + limit_req_zone $ratelimit_key zone=createFeed:10m rate=1r/m; # Limit the number of requests per IP limit_req_zone $limit_feed zone=feed:20m rate=20r/m; - limit_req_zone $limit_createFeed zone=createFeed:10m rate=1r/m; limit_req_zone $limit_key zone=modules:10m rate=30r/m; server { @@ -149,14 +144,14 @@ http { ssl_certificate_key dev_htwkalender_de.key.pem; location /api/feed { + limit_req zone=createFeed nodelay; + limit_req zone=feed burst=10 nodelay; proxy_pass http://htwkalender-ical:8091; client_max_body_size 2m; proxy_connect_timeout 600s; proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s; - limit_req zone=feed burst=10 nodelay; - limit_req zone=createFeed burst=10 nodelay; limit_req_status 429; } diff --git a/reverseproxy.local.conf b/reverseproxy.local.conf index 6d57290..05f99c2 100644 --- a/reverseproxy.local.conf +++ b/reverseproxy.local.conf @@ -1,22 +1,6 @@ -#Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format. -#Copyright (C) 2024 HTWKalender support@htwkalender.de - -#This program is free software: you can redistribute it and/or modify -#it under the terms of the GNU Affero General Public License as published by -#the Free Software Foundation, either version 3 of the License, or -#(at your option) any later version. - -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU Affero General Public License for more details. - -#You should have received a copy of the GNU Affero General Public License -#along with this program. If not, see . - worker_processes 4; -error_log /opt/bitnami/nginx/logs/error.log; +error_log /opt/bitnami/nginx/logs/error.log debug; pid /opt/bitnami/nginx/tmp/nginx.pid; events { @@ -27,61 +11,12 @@ http { include mime.types; default_type application/octet-stream; - gzip on; - gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; - - access_log /opt/bitnami/nginx/logs/proxy_access.log; - error_log /opt/bitnami/nginx/logs/proxy_error.log; - - sendfile on; - keepalive_timeout 180s; - send_timeout 180s; - - client_body_temp_path /opt/bitnami/nginx/tmp/client_temp; - proxy_temp_path /opt/bitnami/nginx/tmp/proxy_temp_path; - fastcgi_temp_path /opt/bitnami/nginx/tmp/fastcgi_temp; - uwsgi_temp_path /opt/bitnami/nginx/tmp/uwsgi_temp; - scgi_temp_path /opt/bitnami/nginx/tmp/scgi_temp; - - proxy_buffering on; - proxy_buffers 8 16k; - proxy_buffer_size 16k; - proxy_busy_buffers_size 64k; - proxy_temp_file_write_size 64k; - proxy_max_temp_file_size 1024m; - - proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Server $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header Host $host; - - geo $admin { - default 1; - #10.0.0.0/8 0; # Private Network - #127.0.0.0/8 0; # Localhost Network - #192.168.0.0/16 0; # Localhost Network - #141.57.0.0/16 0; # HTWK Leipzig Network - #172.16.0.0/12 0; # Private Network - } - - map $admin $limit_key { - 0 ''; - 1 $binary_remote_addr; - } - map $request_method $ratelimit_key { POST $binary_remote_addr; - default $binary_remote_addr; + default ""; } - limit_req_zone $ratelimit_key zone=createFeed:10m rate=1r/s; - #limit_req_zone $limit_key zone=createFeed:10m rate=1r/m; - # Limit the number of requests per IP - limit_req_zone $limit_key zone=feed:20m rate=20r/m; - limit_req_zone $limit_key zone=modules:10m rate=30r/m; - + limit_req_zone $ratelimit_key zone=createFeed:10m rate=1r/m; server { listen 80; @@ -89,13 +24,14 @@ http { http2 on; location /api/feed { + limit_req zone=createFeed nodelay; proxy_pass http://htwkalender-ical:8091; client_max_body_size 20m; proxy_connect_timeout 600s; proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s; - limit_req zone=createFeed nodelay; + limit_req_status 429; } location /api { @@ -109,7 +45,6 @@ http { location /_ { proxy_pass http://htwkalender-data-manager:8090; - # Increase upload file size client_max_body_size 100m; } From e30ef957aaede8abe4742b9e2d2322853e9891c8 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Wed, 19 Jun 2024 22:08:39 +0200 Subject: [PATCH 18/18] fix:#36 reorder limits --- reverseproxy.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reverseproxy.conf b/reverseproxy.conf index 9f0f530..55220e6 100644 --- a/reverseproxy.conf +++ b/reverseproxy.conf @@ -155,8 +155,8 @@ http { server_name htwkalender.de; location /api/feed { - limit_req zone=feed burst=10 nodelay; limit_req zone=createFeed nodelay; + limit_req zone=feed burst=10 nodelay; proxy_pass http://htwkalender-ical:8091; client_max_body_size 2m; proxy_connect_timeout 600s; @@ -192,8 +192,8 @@ http { ssl_certificate_key cal.htwk-leipzig.de.key.pem; location /api/feed { - limit_req zone=feed burst=10 nodelay; limit_req zone=createFeed nodelay; + limit_req zone=feed burst=10 nodelay; proxy_pass http://htwkalender-ical:8091; client_max_body_size 2m; proxy_connect_timeout 600s;