Compare commits

..

89 Commits

Author SHA1 Message Date
413ad0629a 💄 Optimize meet page 2025-04-06 14:49:00 +08:00
aa3c0a9dbf 🐛 Fix meet room page missing channel 2025-04-06 14:41:25 +08:00
00ef003be9 Meet room rendering 2025-04-06 14:30:45 +08:00
e21ec2e81c 🐛 Fix wrong route for rate limiter 2025-03-30 22:58:02 +08:00
4350d197f9 DirectAccess Realm 2025-03-30 14:31:16 +08:00
d5422ab5b0 🐛 Fix nil rdl 2025-03-29 15:59:32 +08:00
4a08fd8f1c Revert to use cached userinfo for security reason 2025-03-29 15:27:29 +08:00
f113ae6cba User info DirectAccess™ 2025-03-29 15:21:30 +08:00
1ea5aea6b3 Prevent from creating multiple redis client 2025-03-29 15:11:07 +08:00
2c4355257c 🚚 Rename CaConn to Conn 2025-03-29 15:02:25 +08:00
69012b9cc3 👔 Make the just added service status up & running 2025-03-29 13:51:53 +08:00
488793a2dc 🐛 Trying to fix cache sdk issue 2025-03-29 13:39:29 +08:00
e7d7cd1000 🐛 Fix nexus allocate did not alloc db in cache 2025-03-29 13:25:46 +08:00
66df1392c4 Advance cachekit API built with gocache/v4 2025-03-29 12:39:15 +08:00
1651328a74 Redis cache 2025-03-29 02:24:15 +08:00
f3f9ebb5af IP Blacklist 2025-03-29 00:26:05 +08:00
105ec693f8 Captcha gateway provide postMessage for better compability 2025-03-23 16:15:34 +08:00
c7f3c1b2cc 🔇 Disable pushing websocket logs 2025-03-23 13:16:13 +08:00
e670724c4c Captcha Gateway Toolkit 2025-03-22 19:50:40 +08:00
62dcbbf424 Captcha Gateway 2025-03-22 19:48:19 +08:00
ba1d96b118 Heavier rate limiting for POST and other methods may create data 2025-03-22 19:23:45 +08:00
c8bba4fb2d 🐛 Increase the header field size limit 2025-03-20 21:34:29 +08:00
7994d1a897 Forward webfinger request 2025-03-11 21:52:47 +08:00
31f29cf940 🐛 Trying to fix unstable ws by limit client id length 2025-03-05 21:52:25 +08:00
8ac88413e0 ♻️ Refactor websocket client id 2025-03-01 14:51:53 +08:00
1f07c0edf4 🔊 More logs in db maintain 2025-03-01 13:27:07 +08:00
74dd8fc182 👔 Reduce deleting recycle deadline 2025-03-01 13:23:25 +08:00
2a5b90b530 Status checking 2025-03-01 13:22:38 +08:00
fe2e682267 ♻️ Replace logger 2025-03-01 13:07:57 +08:00
481404c4a2 🗑️ Clean up command related stuff
🚚 Move http package to web
2025-03-01 13:00:50 +08:00
fbb670b96b Rate limiter 2025-02-25 00:22:46 +08:00
15c39609b8 User info now include the language 2025-02-16 18:38:38 +08:00
4675b65476 🐛 Fix wrong IsAllSuccess value 2025-02-04 14:08:38 +08:00
0f350d00a8 Push stream able to get which request success
⬆️ Upgrade protobuf version
2025-02-02 15:52:00 +08:00
6de240179f Localize toolkit 2025-02-02 13:47:14 +08:00
cf513a7ee8 👔 Optimize watchtower backup format 2025-01-30 23:59:24 +08:00
7942873e21 🐛 Fix .pgpass 2025-01-30 23:33:01 +08:00
6a520603cb ♻️ Use .pgpass file instead stdin enter password 2025-01-30 23:22:43 +08:00
5a71f8268a 🐛 Bug fixes for watchtower backup 2025-01-30 23:08:07 +08:00
22fafa2e84 🔊 Verbose backup db output 2025-01-30 22:53:43 +08:00
2e3c663525 🐛 Keep the nex_user in context always the pointer 2025-01-30 22:44:43 +08:00
7cf9b80fe6 WatchTower admin API 2025-01-30 22:24:58 +08:00
bda9ab6c3d WatchTower for database 2025-01-30 22:14:23 +08:00
734d1e2c35 📝 Add README.md 2025-01-09 19:43:18 +08:00
7f8506e6ea 🐛 Drop just connected service 2024-12-22 14:48:39 +08:00
8e1adfae9a 🐛 Fix user info not found panic 2024-12-22 14:43:02 +08:00
cd58e7a429 🔊 Verbose broadcasting logging 2024-12-03 21:47:24 +08:00
6f2010cb00 Forwarding oidc well-known configuration to id service 2024-11-23 18:23:10 +08:00
25ab137173 Support build jwk from jwt reader 2024-11-23 13:06:05 +08:00
73a8d11c7e 🔊 Verbose event broadcasting 2024-11-23 12:18:35 +08:00
3236ffdebc 🔇 Remove duplicate ws related logs 2024-11-17 21:10:19 +08:00
90741379d6 🔊 Verbose websocket connection logging 2024-11-17 21:01:20 +08:00
ab9bc5d127 🔊 Log when pushing websocket package 2024-11-17 17:38:14 +08:00
c0edeec621 Introducing API Level 2024-11-13 22:26:54 +08:00
f7d82bc93a 🔨 Update build script 2024-11-12 20:48:48 +08:00
c0fec10846 🐛 Bug fixes on check perm 2024-11-04 00:55:38 +08:00
3e68cea0d7 🐛 Fix string perm number value node 2024-11-04 00:53:36 +08:00
e1207a8deb ⬆️ Change encode map json lib 2024-11-04 00:12:17 +08:00
7e4d6bb33f 🐛 Fix grpc call didn't impl 2024-11-03 14:24:03 +08:00
194d270904 Able to get user by using name 2024-11-03 01:40:36 +08:00
ea150608b4 Implement websocket gateway 2024-11-02 13:09:52 +08:00
6bb8eab3fc Add some directly callable functions into adaptor 2024-10-31 21:31:56 +08:00
aa624ee454 🧑‍💻 Add more user related query rpc call 2024-10-31 20:57:27 +08:00
32a77f7f0f 🗑️ Remove macos system file 2024-10-31 20:53:27 +08:00
3f6ea11d22 🐛 Fix on reading jwt claims 2024-10-30 23:59:04 +08:00
f9b6cd2e20 🐛 Fix reading jwt issue 2024-10-30 23:44:25 +08:00
06c5fadb42 💥 Change read jwt SDK api 2024-10-30 23:39:09 +08:00
427c83e38f 🐛 Fix read jwt handle claims wrong 2024-10-30 23:36:33 +08:00
a785adfafa 🐛 Bug fixes on auth 2024-10-30 23:26:39 +08:00
ae3583ead1 🐛 Fix UserInfo cannot store in database 2024-10-27 13:12:35 +08:00
7fd0b7695e Add perm check helper in Nex.Sec 2024-10-27 13:08:30 +08:00
26a9e62a17 Nexus will refer broadcast event request 2024-10-27 12:54:39 +08:00
6645a60b30 🐛 Bug fixes 2024-10-27 00:46:54 +08:00
d588b0723b 🐛 Fix all route validate the auth state 2024-10-27 00:36:06 +08:00
3d487fa48b 🐛 Fix auth middlewares 2024-10-27 00:20:44 +08:00
999cc2bcd8 🐛 Fix auth context middleware force provide token 2024-10-27 00:14:42 +08:00
421834ae5c Nex.Rx, and easier to use alloc mq apis 2024-10-24 23:52:38 +08:00
23d14e4e46 MQ, KV and MQ allocator 2024-10-24 23:46:09 +08:00
aa67bd0b8f Service validation 2024-10-24 23:26:24 +08:00
1b5b2c42e5 Add service type for pusher 2024-10-24 22:40:14 +08:00
f51b22f0e8 🐛 Fix check perm still require session id 2024-10-24 00:38:29 +08:00
a5117e76d6 🐛 Fix internal token load keypair issue 2024-10-23 22:31:47 +08:00
a1412acc90 Provide external apis for ability of auth 2024-10-22 23:23:58 +08:00
0f4112e08b Fetch userinfo in auth middleware 2024-10-22 22:58:09 +08:00
406031b966 📝 Roadmap 2024-10-22 00:19:04 +08:00
ed05782319 Auth stuff 2024-10-22 00:12:28 +08:00
85783aa331 🧱 Introduce etcd for high availability (HA) 2024-10-21 22:47:31 +08:00
f6ff7178b9 ⬆️ Upgrade deps 2024-10-21 22:15:45 +08:00
87a7eb8f45 🚚 Rename protobuf 2024-10-21 22:07:36 +08:00
110 changed files with 5721 additions and 3172 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -25,4 +25,4 @@ jobs:
context: .
file: ./Dockerfile
push: true
tags: xsheep2010/dealer:nightly
tags: xsheep2010/nexus:nightly

7
.gitignore vendored
View File

@@ -1,2 +1,7 @@
/dist
/uploads
/uploads
/default.etcd
/keys
.idea
.DS_Store

12
.idea/protoeditor.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProtobufLanguageSettings">
<option name="importPathEntries">
<list>
<ImportPathEntry>
<option name="location" value="file://$PROJECT_DIR$/pkg/proto" />
</ImportPathEntry>
</list>
</option>
</component>
</project>

View File

@@ -1,7 +1,5 @@
# Building Backend
FROM golang:alpine as dealer-server
RUN apk add nodejs npm
FROM golang:alpine as nexus-server
WORKDIR /source
COPY . .
@@ -12,8 +10,11 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -buildvcs -o /dist ./pkg/main
# Runtime
FROM golang:alpine
COPY --from=dealer-server /dist /dealer/server
RUN apk add postgresql-client
COPY --from=nexus-server /dist /nexus/server
COPY ./templates /templates
EXPOSE 8444
CMD ["/dealer/server"]
CMD ["/nexus/server"]

107
README.md Normal file
View File

@@ -0,0 +1,107 @@
# HyperNet.Nexus
Nexus is the core component of HyperNet,
which managed the resources allocation (such as the database allocate and more)
and the service gateway.
## Features
### Gateway
Gateway is one of the core features in Nexus, every HyperNet services will establish a connection to the Nexus
when they start. And it is required, if Nexus is died or it did not connected it successfully, the service will exit.
During the registration, the service will provide follow details:
1. An unique service ID - `id`
2. The human readable name of the service - `label`
3. The code for accessing the service - `type`
4. The grpc outbound address of the service - `grpc_addr`
5. The http outbound address of the service - `http_addr`
There is two kind of the gateway, the grpc one and the http one.
When the user requested the `/cgi/<type>`, the request was forwarded to the `http_addr`
of the service with load balancer included.
And when the internal service call `GetServiceGrpcConn(type)`, the Nexus will run a health check to ensure the
target service is alive and respond with a `grpc_addr`, the rest of the connection will be handled by the SDK.
It is also load balancer included.
### Allocation
The allocation is the additional service which make our developer experience better.
For simple, the allocation is basically a improved version of the shared configuration.
With some part of the configuration will be re-configured according to the service's demand.
Like the database allocation, service request with the database name they want,
and the Nexus will respond a configured connection string to the service, then the SDK will handle
the establishment of the connection.
At the same time, the allocated database will be added into the watchtower for auto maintenance
(auto remove the soft-deleted records, backup and more).
Currently, the database is only support postgres, there is no plan for supporting other databases.
### Authorization
All the request forwarded by the Nexus will handle the authorization automatically.
The Authorization header field will be replaced by the internal one with full user data.
To implement the authorization, you must have at least one [Passport](https://github.com/Solsynth/HyperNet.Passport) instance alive.
For further usage, checkout the `hypernet/nexus/pkg/nex/sec` package.
## Installation
To run the Nexus, you need to have an etcd server and a nats server running.
The best way to run the Nexus is using docker compose. Here is an example with the required dependencies added
and health check configured:
```yaml
services:
nexus:
image: xsheep2010/nexus:nightly
network_mode: "host"
restart: unless-stopped
depends_on:
- nats
- etcd
volumes:
- "/srv/hypernet/nexus.settings.toml:/settings.toml"
- "/srv/hypernet/keys:/keys"
healthcheck:
test: ["CMD", "nc", "-z", "localhost", "7001"]
interval: 30s
timeout: 5s
retries: 5
start_period: 15s
nats:
image: nats:latest
network_mode: "host"
restart: unless-stopped
etcd:
image: bitnami/etcd:latest
network_mode: "host"
restart: unless-stopped
environment:
- ALLOW_NONE_AUTHENTICATION=yes
```
To add more services, you can according follow example:
```yaml
services:
passport:
image: xsheep2010/passport:nightly
network_mode: "host"
restart: unless-stopped
depends_on:
nexus:
condition: service_healthy
volumes:
- "/srv/hypernet/passport.settings.toml:/settings.toml"
- "/srv/hypernet/keys:/keys"
```

129
go.mod
View File

@@ -1,95 +1,106 @@
module git.solsynth.dev/hypernet/nexus
go 1.21.6
toolchain go1.22.1
go 1.22.0
require (
github.com/fatih/color v1.17.0
github.com/eko/gocache/lib/v4 v4.2.0
github.com/eko/gocache/store/redis/v4 v4.2.2
github.com/fatih/color v1.18.0
github.com/go-playground/validator/v10 v10.22.1
github.com/goccy/go-json v0.10.3
github.com/gofiber/contrib/websocket v1.3.0
github.com/gofiber/fiber/v2 v2.52.4
github.com/gofiber/contrib/fiberzerolog v1.0.2
github.com/gofiber/contrib/websocket v1.3.2
github.com/gofiber/fiber/v2 v2.52.6
github.com/gofiber/template/html/v2 v2.1.3
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/uuid v1.6.0
github.com/json-iterator/go v1.1.12
github.com/lib/pq v1.10.9
github.com/mbobakov/grpc-consul-resolver v1.5.3
github.com/nats-io/nats.go v1.37.0
github.com/nicksnyder/go-i18n/v2 v2.5.0
github.com/redis/go-redis/v9 v9.7.3
github.com/robfig/cron/v3 v3.0.1
github.com/rs/zerolog v1.31.0
github.com/samber/lo v1.39.0
github.com/spf13/viper v1.18.2
google.golang.org/grpc v1.65.0
google.golang.org/protobuf v1.34.2
gorm.io/datatypes v1.2.0
gorm.io/driver/postgres v1.5.4
gorm.io/gorm v1.25.6
github.com/rs/zerolog v1.33.0
github.com/samber/lo v1.47.0
github.com/spf13/viper v1.19.0
github.com/valyala/fasthttp v1.59.0
go.etcd.io/etcd/client/v3 v3.5.16
golang.org/x/text v0.22.0
google.golang.org/grpc v1.67.1
google.golang.org/protobuf v1.35.1
gorm.io/datatypes v1.2.4
gorm.io/driver/postgres v1.5.9
gorm.io/gorm v1.25.12
)
require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/fasthttp/websocket v1.5.8 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fasthttp/websocket v1.5.10 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-playground/form v3.1.4+incompatible // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/consul/api v1.29.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/gofiber/template v1.8.3 // indirect
github.com/gofiber/utils v1.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgx/v5 v5.5.1 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.7.1 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/philhofer/fwd v1.1.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/nats-io/nkeys v0.4.7 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.52.3 // indirect
github.com/prometheus/procfs v0.13.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tinylib/msgp v1.1.8 // indirect
github.com/tinylib/msgp v1.2.5 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.52.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
go.etcd.io/etcd/api/v3 v3.5.16 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.33.0 // indirect
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.30.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/mysql v1.5.2 // indirect
gorm.io/driver/mysql v1.5.7 // indirect
)
replace git.solsynth.dev/hydrogen/bus => ../Bus

459
go.sum
View File

@@ -1,415 +1,294 @@
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fasthttp/websocket v1.5.8 h1:k5DpirKkftIF/w1R8ZzjSgARJrs54Je9YJK37DL/Ah8=
github.com/fasthttp/websocket v1.5.8/go.mod h1:d08g8WaT6nnyvg9uMm8K9zMYyDjfKyj3170AtPRuVU0=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/eko/gocache/lib/v4 v4.2.0 h1:MNykyi5Xw+5Wu3+PUrvtOCaKSZM1nUSVftbzmeC7Yuw=
github.com/eko/gocache/lib/v4 v4.2.0/go.mod h1:7ViVmbU+CzDHzRpmB4SXKyyzyuJ8A3UW3/cszpcqB4M=
github.com/eko/gocache/store/redis/v4 v4.2.2 h1:Thw31fzGuH3WzJywsdbMivOmP550D6JS7GDHhvCJPA0=
github.com/eko/gocache/store/redis/v4 v4.2.2/go.mod h1:LaTxLKx9TG/YUEybQvPMij++D7PBTIJ4+pzvk0ykz0w=
github.com/fasthttp/websocket v1.5.10 h1:bc7NIGyrg1L6sd5pRzCIbXpro54SZLEluZCu0rOpcN4=
github.com/fasthttp/websocket v1.5.10/go.mod h1:BwHeuXGWzCW1/BIKUKD3+qfCl+cTdsHu/f243NcAI/Q=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
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/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
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/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/form v3.1.4+incompatible h1:lvKiHVxE2WvzDIoyMnWcjyiBxKt2+uFJyZcPYWsLnjI=
github.com/go-playground/form v3.1.4+incompatible/go.mod h1:lhcKXfTuhRtIZCIKUeJ0b5F207aeQCPbZU09ScKjwWg=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74=
github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
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/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofiber/contrib/websocket v1.3.0 h1:XADFAGorer1VJ1bqC4UkCjqS37kwRTV0415+050NrMk=
github.com/gofiber/contrib/websocket v1.3.0/go.mod h1:xguaOzn2ZZ759LavtosEP+rcxIgBEE/rdumPINhR+Xo=
github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gofiber/contrib/fiberzerolog v1.0.2 h1:LMa/luarQVeINoRwZLHtLQYepLPDIwUNB5OmdZKk+s8=
github.com/gofiber/contrib/fiberzerolog v1.0.2/go.mod h1:aTPsgArSgxRWcUeJ/K6PiICz3mbQENR1QOR426QwOoQ=
github.com/gofiber/contrib/websocket v1.3.2 h1:AUq5PYeKwK50s0nQrnluuINYeep1c4nRCJ0NWsV3cvg=
github.com/gofiber/contrib/websocket v1.3.2/go.mod h1:07u6QGMsvX+sx7iGNCl5xhzuUVArWwLQ3tBIH24i+S8=
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
github.com/gofiber/template/html/v2 v2.1.3 h1:n1LYBtmr9C0V/k/3qBblXyMxV5B0o/gpb6dFLp8ea+o=
github.com/gofiber/template/html/v2 v2.1.3/go.mod h1:U5Fxgc5KpyujU9OqKzy6Kn6Qup6Tm7zdsISR+VpnHRE=
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
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/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
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/hashicorp/consul/api v1.29.1 h1:UEwOjYJrd3lG1x5w7HxDRMGiAUPrb3f103EoeKuuEcc=
github.com/hashicorp/consul/api v1.29.1/go.mod h1:lumfRkY/coLuqMICkI7Fh3ylMG31mQSRZyef2c5YvJI=
github.com/hashicorp/consul/proto-public v0.6.1 h1:+uzH3olCrksXYWAYHKqK782CtK9scfqH+Unlw3UHhCg=
github.com/hashicorp/consul/proto-public v0.6.1/go.mod h1:cXXbOg74KBNGajC+o8RlA502Esf0R9prcoJgiOX/2Tg=
github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg=
github.com/hashicorp/consul/sdk v0.16.1/go.mod h1:fSXvwxB2hmh1FMZCNl6PwX0Q/1wdWtHJcZ7Ea5tns0s=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM=
github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.5.1 h1:5I9etrGkLrN+2XPCsi6XLlV5DITbSL/xBZdmAxFcXPI=
github.com/jackc/pgx/v5 v5.5.1/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
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.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
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-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mbobakov/grpc-consul-resolver v1.5.3 h1:xL7nJm8qCvxgHMqlnF4naXruBUoHqfUWORl3UmwKByU=
github.com/mbobakov/grpc-consul-resolver v1.5.3/go.mod h1:0wN8+McBocuk5mO9xlAfrmBSothm7sps43bFGubg0m4=
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE=
github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nicksnyder/go-i18n/v2 v2.5.0 h1:3wH1gpaekcgGuwzWdSu7JwJhH9Tk87k1ezt0i1p2/Is=
github.com/nicksnyder/go-i18n/v2 v2.5.0/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
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/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 h1:KanIMPX0QdEdB4R3CiimCAbxFrhB3j7h0/OvpYGVQa8=
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc=
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
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/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
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/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/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/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
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/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
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/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=
github.com/valyala/fasthttp v1.59.0 h1:Qu0qYHfXvPk1mSLNqcFtEk6DpxgA26hy6bmydotDpRI=
github.com/valyala/fasthttp v1.59.0/go.mod h1:GTxNb9Bc6r2a9D0TWNSPwDz78UxnTGBViY3xZNEqyYU=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/etcd/api/v3 v3.5.16 h1:WvmyJVbjWqK4R1E+B12RRHz3bRGy9XVfh++MgbN+6n0=
go.etcd.io/etcd/api/v3 v3.5.16/go.mod h1:1P4SlIP/VwkDmGo3OlOD7faPeP8KDIFhqvciH5EfN28=
go.etcd.io/etcd/client/pkg/v3 v3.5.16 h1:ZgY48uH6UvB+/7R9Yf4x574uCO3jIx0TRDyetSfId3Q=
go.etcd.io/etcd/client/pkg/v3 v3.5.16/go.mod h1:V8acl8pcEK0Y2g19YlOV9m9ssUe6MgiDSobSoaBAM0E=
go.etcd.io/etcd/client/v3 v3.5.16 h1:sSmVYOAHeC9doqi0gv7v86oY/BTld0SEFGaxsU9eRhE=
go.etcd.io/etcd/client/v3 v3.5.16/go.mod h1:X+rExSGkyqxvu276cr2OwPLBaeqFu1cIl4vmRjAD/50=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.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.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
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.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
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.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 h1:2oV8dfuIkM1Ti7DwXc0BJfnwr9csz4TDXI9EmiI+Rbw=
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38/go.mod h1:vuAjtvlwkDKF6L1GQ0SokiRLCGFfeBUXWr/aFFkHACc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/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=
gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco=
gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04=
gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo=
gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0=
gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU=
gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.6 h1:V92+vVda1wEISSOMtodHVRcUIOPYa2tgQtyF+DfFx+A=
gorm.io/gorm v1.25.6/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

0
ip_block.list Normal file
View File

BIN
pkg/.DS_Store vendored

Binary file not shown.

33
pkg/internal/auth/http.go Normal file
View File

@@ -0,0 +1,33 @@
package auth
import (
"github.com/gofiber/fiber/v2"
)
func ContextMiddleware(c *fiber.Ctx) error {
atk := tokenExtract(c)
if len(atk) == 0 {
return c.Next()
}
c.Locals("nex_in_token", atk)
if claims, err := tokenRead(atk); err == nil && claims != nil {
c.Locals("nex_principal", claims)
if err = userinfoFetch(c); err != nil {
return err
}
} else if err != nil {
return fiber.NewError(fiber.StatusUnauthorized, err.Error())
}
return c.Next()
}
func ValidatorMiddleware(c *fiber.Ctx) error {
if c.Locals("nex_principal") == nil {
return fiber.NewError(fiber.StatusUnauthorized, "unauthorized")
}
return c.Next()
}

View File

@@ -0,0 +1,36 @@
package auth
import (
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"github.com/gofiber/fiber/v2"
"strings"
)
var JReader *sec.JwtReader
var IReader *sec.InternalTokenReader
var IWriter *sec.InternalTokenWriter
func tokenExtract(c *fiber.Ctx) string {
var atk string
if cookie := c.Cookies(sec.CookieAccessToken); len(cookie) > 0 {
atk = cookie
}
if header := c.Get(fiber.HeaderAuthorization); len(header) > 0 {
tk := strings.Replace(header, "Bearer", "", 1)
atk = strings.TrimSpace(tk)
}
if tk := c.Query("tk"); len(tk) > 0 {
atk = strings.TrimSpace(tk)
}
return atk
}
func tokenRead(in string) (*sec.JwtClaims, error) {
if JReader == nil {
return nil, nil
}
claims, err := sec.ReadJwt[*sec.JwtClaims](JReader, in, &sec.JwtClaims{})
return claims, err
}

View File

@@ -0,0 +1,53 @@
package auth
import (
"context"
"fmt"
"strconv"
"time"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)
func userinfoFetch(c *fiber.Ctx) error {
claims, ok := c.Locals("nex_principal").(*sec.JwtClaims)
if !ok {
return fiber.NewError(fiber.StatusUnauthorized, "user principal data was not found")
}
service := directory.GetServiceInstanceByType(nex.ServiceTypeAuth)
if service != nil {
conn, err := service.GetGrpcConn()
if err != nil {
log.Warn().Str("id", service.ID).Err(err).Msg("Unable to fetch userinfo, the implementation of id service is down")
} else {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
sed, err := strconv.Atoi(claims.Session)
if err != nil {
return fiber.NewError(fiber.StatusUnauthorized, "invalid token payload")
}
resp, err := proto.NewAuthServiceClient(conn).Authenticate(ctx, &proto.AuthRequest{
SessionId: uint64(sed),
})
if err != nil {
return fiber.NewError(fiber.StatusUnauthorized, fmt.Sprintf("unable to load userinfo: %v", err))
}
userinfo := sec.NewUserInfoFromProto(resp.Info.Info)
c.Locals("nex_user", &userinfo)
tk, err := IWriter.WriteUserInfoJwt(userinfo)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("unable to sign userinfo: %v", err))
}
c.Locals("nex_token", tk)
}
} else {
log.Warn().Msg("Unable to fetch userinfo, no implementation of id service")
}
return nil
}

26
pkg/internal/cache/redis.go vendored Normal file
View File

@@ -0,0 +1,26 @@
package cache
import (
"time"
"git.solsynth.dev/hypernet/nexus/pkg/nex/cachekit"
"github.com/redis/go-redis/v9"
)
var (
Rdb *redis.Client
Kcc *cachekit.Conn
)
func ConnectRedis(addr, password string, db int) error {
Rdb = redis.NewClient(&redis.Options{
Addr: addr,
Password: password,
DB: db,
})
Kcc = &cachekit.Conn{
Rd: Rdb,
Timeout: 3 * time.Second,
}
return nil
}

View File

@@ -0,0 +1,33 @@
package captcha
import (
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
type TemplateData struct {
ApiKey string `json:"api_key"`
}
func GetTemplateData() TemplateData {
return TemplateData{
ApiKey: viper.GetString("captcha.api_key"),
}
}
type CaptchaAdapter interface {
Validate(token, ip string) bool
}
var adapters = map[string]CaptchaAdapter{
"turnstile": &TurnstileAdapter{},
}
func Validate(token, ip string) bool {
provider := viper.GetString("captcha.provider")
if adapter, ok := adapters[provider]; ok {
return adapter.Validate(token, ip)
}
log.Error().Msg("Unable to handle captcha validate request due to unsupported provider.")
return false
}

View File

@@ -0,0 +1,46 @@
package captcha
import (
"bytes"
"encoding/json"
"net/http"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
type TurnstileAdapter struct{}
type turnstileResponse struct {
Success bool `json:"success"`
ErrorCodes []string `json:"error-codes"`
}
func (a *TurnstileAdapter) Validate(token, ip string) bool {
url := "https://challenges.cloudflare.com/turnstile/v0/siteverify"
data := map[string]string{
"secret": viper.GetString("captcha.api_secret"),
"response": token,
"remoteip": ip,
}
jsonData, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
log.Error().Err(err).Msg("Error sending request to Turnstile...")
return false
}
defer resp.Body.Close()
var result turnstileResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
log.Error().Err(err).Msg("Error decoding response from Turnstile...")
return false
}
if !result.Success {
log.Warn().Strs("errors", result.ErrorCodes).Msg("An captcha validation request failed...")
}
return result.Success
}

View File

@@ -2,9 +2,11 @@ package database
import (
"fmt"
"strings"
"git.solsynth.dev/hypernet/nexus/pkg/internal/watchtower"
"github.com/samber/lo"
"github.com/spf13/viper"
"strings"
)
func AllocDatabase(name string) (string, error) {
@@ -34,6 +36,9 @@ func AllocDatabase(name string) (string, error) {
}
connString = append(connString, "dbname="+name)
dsn := strings.Join(connString, " ")
return strings.Join(connString, " "), nil
watchtower.AddWatchDb(dsn)
return dsn, nil
}

View File

@@ -1,22 +0,0 @@
package directory
const (
CommandMethodGet = "get"
CommandMethodPut = "put"
CommandMethodPatch = "patch"
CommandMethodPost = "post"
CommandMethodDelete = "delete"
)
type Command struct {
// The unique identifier of the command, different method command can hold the same command id
ID string `json:"id"`
// The method of the command, such as get, post, others; inspired by RESTful design
Method string `json:"method"`
// The tags of the command will be used to invoke the pre-command middlewares and post-command middlewares
Tags []string `json:"tags"`
// The implementation of the command, the handler is the service that will be invoked
Handler []*ServiceInstance `json:"handler"`
robinIndex uint
}

View File

@@ -1,67 +0,0 @@
package directory
import (
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
"strings"
"sync"
)
// In commands, we use the map and the mutex because it is usually read and only sometimes write
var commandDirectory = make(map[string]*Command)
var commandDirectoryMutex sync.Mutex
func AddCommand(id, method string, tags []string, handler *ServiceInstance) {
commandDirectoryMutex.Lock()
defer commandDirectoryMutex.Unlock()
if tags == nil {
tags = make([]string, 0)
}
ky := nex.GetCommandKey(id, method)
if _, ok := commandDirectory[ky]; !ok {
commandDirectory[ky] = &Command{
ID: id,
Method: method,
Tags: tags,
Handler: []*ServiceInstance{handler},
}
} else {
commandDirectory[ky].Handler = append(commandDirectory[ky].Handler, handler)
commandDirectory[ky].Tags = lo.Uniq(append(commandDirectory[ky].Tags, tags...))
}
commandDirectory[ky].Handler = lo.UniqBy(commandDirectory[ky].Handler, func(item *ServiceInstance) string {
return item.ID
})
log.Info().Str("id", id).Str("method", method).Str("tags", strings.Join(tags, ",")).Msg("New command registered")
}
func GetCommandHandler(id, method string) *ServiceInstance {
commandDirectoryMutex.Lock()
defer commandDirectoryMutex.Unlock()
ky := nex.GetCommandKey(id, method)
if val, ok := commandDirectory[ky]; ok {
if len(val.Handler) == 0 {
return nil
}
idx := val.robinIndex % uint(len(val.Handler))
val.robinIndex = idx + 1
return val.Handler[idx]
}
return nil
}
func RemoveCommand(id, method string) {
commandDirectoryMutex.Lock()
defer commandDirectoryMutex.Unlock()
ky := nex.GetCommandKey(id, method)
delete(commandDirectory, ky)
}

View File

@@ -1,116 +0,0 @@
package directory
import (
"context"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"io"
"net/http"
"time"
)
type CommandRpcServer struct {
proto.UnimplementedCommandControllerServer
}
func (c CommandRpcServer) AddCommand(ctx context.Context, info *proto.CommandInfo) (*proto.AddCommandResponse, error) {
clientId, err := GetClientId(ctx)
if err != nil {
return nil, err
}
service := GetServiceInstance(clientId)
if service == nil {
return nil, status.Errorf(codes.NotFound, "service not found")
}
AddCommand(info.GetId(), info.GetMethod(), info.GetTags(), service)
return &proto.AddCommandResponse{
IsSuccess: true,
}, nil
}
func (c CommandRpcServer) RemoveCommand(ctx context.Context, request *proto.CommandLookupRequest) (*proto.RemoveCommandResponse, error) {
RemoveCommand(request.GetId(), request.GetMethod())
return &proto.RemoveCommandResponse{
IsSuccess: true,
}, nil
}
func (c CommandRpcServer) SendCommand(ctx context.Context, argument *proto.CommandArgument) (*proto.CommandReturn, error) {
id := argument.GetCommand()
method := argument.GetMethod()
handler := GetCommandHandler(id, method)
if handler == nil {
return &proto.CommandReturn{
IsDelivered: false,
Status: http.StatusNotFound,
ContentType: "text/plain+error",
Payload: []byte("command not found"),
}, nil
}
conn, err := handler.GetGrpcConn()
if err != nil {
return &proto.CommandReturn{
IsDelivered: false,
Status: http.StatusServiceUnavailable,
ContentType: "text/plain+error",
Payload: []byte("service unavailable"),
}, nil
}
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
out, err := proto.NewCommandControllerClient(conn).SendCommand(ctx, argument)
if err != nil {
return &proto.CommandReturn{
IsDelivered: true,
Status: http.StatusInternalServerError,
ContentType: "text/plain+error",
Payload: []byte(err.Error()),
}, nil
}
out.IsDelivered = true
return out, nil
}
func (c CommandRpcServer) SendStreamCommand(g grpc.BidiStreamingServer[proto.CommandArgument, proto.CommandReturn]) error {
for {
pck, err := g.Recv()
if err == io.EOF {
return nil
} else if err != nil {
return err
}
id := pck.GetCommand()
method := pck.GetMethod()
handler := GetCommandHandler(id, method)
if handler == nil {
return status.Errorf(codes.NotFound, "command not found")
}
conn, err := handler.GetGrpcConn()
ctx, cancel := context.WithTimeout(g.Context(), time.Second*10)
out, err := proto.NewCommandControllerClient(conn).SendCommand(ctx, pck)
cancel()
if err != nil {
_ = g.Send(&proto.CommandReturn{
IsDelivered: false,
Status: http.StatusInternalServerError,
ContentType: "text/plain+error",
Payload: []byte(err.Error()),
})
} else {
_ = g.Send(out)
}
}
}

View File

@@ -1,6 +1,8 @@
package directory
import "google.golang.org/grpc"
import (
"google.golang.org/grpc"
)
type ServiceInstance struct {
ID string `json:"id"`
@@ -9,21 +11,22 @@ type ServiceInstance struct {
GrpcAddr string `json:"grpc_addr"`
HttpAddr *string `json:"http_addr"`
grpcConn *grpc.ClientConn
retryCount int
}
var connectionCache = make(map[string]*grpc.ClientConn)
func (v *ServiceInstance) GetGrpcConn() (*grpc.ClientConn, error) {
if v.grpcConn != nil {
return v.grpcConn, nil
if conn, ok := connectionCache[v.ID]; ok {
return conn, nil
}
var err error
v.grpcConn, err = ConnectService(v)
conn, err := ConnectService(v)
if err != nil {
RemoveServiceInstance(v.ID)
return nil, err
} else {
connectionCache[v.ID] = conn
}
return v.grpcConn, nil
return conn, nil
}

View File

@@ -2,77 +2,149 @@ package directory
import (
"context"
"math/rand"
"time"
"git.solsynth.dev/hypernet/nexus/pkg/internal/kv"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"sync"
"time"
"github.com/goccy/go-json"
"github.com/rs/zerolog/log"
clientv3 "go.etcd.io/etcd/client/v3"
)
// In services, we use sync.Map because it will be both often read and write
var serviceDirectory sync.Map
const ServiceInfoKvPrefix = "nexus.service/"
func GetServiceInstance(id string) *ServiceInstance {
val, ok := serviceDirectory.Load(id)
if ok {
return val.(*ServiceInstance)
} else {
return nil
func AddServiceInstance(in *ServiceInstance) error {
key := ServiceInfoKvPrefix + in.ID
data, err := json.Marshal(in)
if err != nil {
return err
}
_, err = kv.Kv.Put(context.Background(), key, string(data))
SetServiceStatus(in.Type, true)
return err
}
func GetServiceInstanceByType(t string) *ServiceInstance {
var result *ServiceInstance
serviceDirectory.Range(func(key, value any) bool {
if value.(*ServiceInstance).Type == t {
result = value.(*ServiceInstance)
return false
}
return true
})
return result
func GetServiceInstance(id string) *ServiceInstance {
key := ServiceInfoKvPrefix + id
resp, err := kv.Kv.Get(context.Background(), key)
if err != nil || len(resp.Kvs) == 0 {
return nil
}
var instance ServiceInstance
err = json.Unmarshal(resp.Kvs[0].Value, &instance)
if err != nil {
return nil
}
return &instance
}
func ListServiceInstance() []*ServiceInstance {
resp, err := kv.Kv.Get(context.Background(), ServiceInfoKvPrefix, clientv3.WithPrefix())
if err != nil {
return nil
}
var result []*ServiceInstance
serviceDirectory.Range(func(key, value interface{}) bool {
result = append(result, value.(*ServiceInstance))
return true
})
for _, val := range resp.Kvs {
var instance ServiceInstance
if err := json.Unmarshal(val.Value, &instance); err != nil {
continue
}
result = append(result, &instance)
}
return result
}
func ListServiceInstanceByType(t string) []*ServiceInstance {
resp, err := kv.Kv.Get(context.Background(), ServiceInfoKvPrefix, clientv3.WithPrefix())
if err != nil {
return nil
}
var result []*ServiceInstance
serviceDirectory.Range(func(key, value interface{}) bool {
if value.(*ServiceInstance).Type == t {
result = append(result, value.(*ServiceInstance))
for _, val := range resp.Kvs {
var instance ServiceInstance
if err := json.Unmarshal(val.Value, &instance); err != nil {
continue
}
return true
})
if instance.Type == t {
result = append(result, &instance)
}
}
return result
}
func AddServiceInstance(in *ServiceInstance) {
serviceDirectory.Store(in.ID, in)
var srvRng = rand.New(rand.NewSource(time.Now().UnixNano()))
func GetServiceInstanceByType(t string) *ServiceInstance {
resp, err := kv.Kv.Get(context.Background(), ServiceInfoKvPrefix, clientv3.WithPrefix())
if err != nil {
return nil
}
var instances []*ServiceInstance
for _, val := range resp.Kvs {
var instance ServiceInstance
if err := json.Unmarshal(val.Value, &instance); err != nil {
continue
}
if instance.Type == t {
instances = append(instances, &instance)
}
}
if len(instances) == 0 {
return nil
}
idx := srvRng.Intn(len(instances))
return instances[idx]
}
func RemoveServiceInstance(id string) {
serviceDirectory.Delete(id)
func RemoveServiceInstance(id string) error {
key := ServiceInfoKvPrefix + id
_, err := kv.Kv.Delete(context.Background(), key)
return err
}
func BroadcastEvent(event string, data any) {
serviceDirectory.Range(func(key, value any) bool {
conn, err := value.(*ServiceInstance).GetGrpcConn()
func BroadcastEvent(event string, data any) error {
resp, err := kv.Kv.Get(context.Background(), ServiceInfoKvPrefix, clientv3.WithPrefix())
if err != nil {
return err
}
log.Debug().
Int("destinations", len(resp.Kvs)).
Str("event", event).
Msg("Broadcasting event from internal...")
for idx, val := range resp.Kvs {
var instance ServiceInstance
if err := json.Unmarshal(val.Value, &instance); err != nil {
log.Error().Err(err).Int("index", idx).
Msg("Unable to parse instance config, skip broadcasting for it...")
continue
}
conn, err := instance.GetGrpcConn()
if err != nil {
return true
log.Error().Err(err).Str("destination", instance.ID).
Msg("Unable to get grpc connection, skip broadcasting for it...")
continue
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
_, _ = proto.NewServiceDirectoryClient(conn).BroadcastEvent(ctx, &proto.EventInfo{
_, _ = proto.NewDirectoryServiceClient(conn).BroadcastEvent(ctx, &proto.EventInfo{
Event: event,
Data: nex.EncodeMap(data),
})
return true
})
cancel()
}
return nil
}

View File

@@ -12,7 +12,7 @@ import (
)
type ServiceRpcServer struct {
proto.UnimplementedServiceDirectoryServer
proto.UnimplementedDirectoryServiceServer
}
func instantiationService(in *ServiceInstance) *proto.ServiceInfo {
@@ -66,6 +66,8 @@ func (v *ServiceRpcServer) AddService(ctx context.Context, info *proto.ServiceIn
if info.GetId() != clientId {
return nil, status.Errorf(codes.InvalidArgument, "client_id mismatch in metadata")
} else if len(clientId) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "client_id must not be blank")
}
in := &ServiceInstance{
@@ -75,17 +77,42 @@ func (v *ServiceRpcServer) AddService(ctx context.Context, info *proto.ServiceIn
GrpcAddr: info.GetGrpcAddr(),
HttpAddr: info.HttpAddr,
}
AddServiceInstance(in)
log.Info().Str("id", clientId).Str("label", info.GetLabel()).Msg("New service registered")
err = AddServiceInstance(in)
if err == nil {
log.Info().Str("id", clientId).Str("label", info.GetLabel()).Msg("New service registered")
} else {
log.Error().Str("id", clientId).Str("label", info.GetLabel()).Err(err).Msg("Unable to register a service")
}
return &proto.AddServiceResponse{
IsSuccess: true,
IsSuccess: err == nil,
}, nil
}
func (v *ServiceRpcServer) RemoveService(ctx context.Context, request *proto.RemoveServiceRequest) (*proto.RemoveServiceResponse, error) {
RemoveServiceInstance(request.GetId())
log.Info().Str("id", request.GetId()).Msg("A service removed.")
err := RemoveServiceInstance(request.GetId())
if err == nil {
log.Info().Str("id", request.GetId()).Msg("A service removed")
} else {
log.Error().Str("id", request.GetId()).Err(err).Msg("Unable to remove a service")
}
return &proto.RemoveServiceResponse{
IsSuccess: true,
IsSuccess: err == nil,
}, nil
}
func (v *ServiceRpcServer) BroadcastEvent(ctx context.Context, in *proto.EventInfo) (*proto.EventResponse, error) {
services := ListServiceInstance()
log.Debug().
Int("destinations", len(services)).
Str("event", in.GetEvent()).
Msg("Broadcasting event...")
for _, service := range services {
conn, err := service.GetGrpcConn()
if err != nil {
continue
}
_, _ = proto.NewDirectoryServiceClient(conn).BroadcastEvent(ctx, in)
}
return &proto.EventResponse{}, nil
}

View File

@@ -0,0 +1,72 @@
package directory
import (
"sync"
"github.com/rs/zerolog/log"
)
var (
statusOfServices = make(map[string]bool)
statusLock sync.Mutex
)
func GetServiceStatus() map[string]bool {
out := make(map[string]bool)
for k, v := range statusOfServices {
out[k] = v
}
services := ListServiceInstance()
for _, service := range services {
if _, ok := out[service.Type]; !ok {
out[service.Type] = false
}
}
return out
}
func SetServiceStatus(t string, status bool) {
statusLock.Lock()
defer statusLock.Unlock()
statusOfServices[t] = status
}
func ValidateServices() {
statusLock.Lock()
defer statusLock.Unlock()
services := ListServiceInstance()
if len(services) == 0 {
return
}
checklist := make(map[string]bool)
successCount := 0
log.Info().Int("count", len(services)).Msg("Validating services...")
for _, service := range services {
if _, ok := checklist[service.GrpcAddr]; ok {
_ = RemoveServiceInstance(service.ID)
log.Warn().Str("id", service.ID).Str("addr", service.GrpcAddr).Msg("Duplicated service address, dropped...")
continue
}
// Directly use the connect method to skip cache
if _, err := ConnectService(service); err != nil {
statusOfServices[service.Type] = false
_ = RemoveServiceInstance(service.ID)
log.Warn().Err(err).Str("id", service.ID).Str("addr", service.GrpcAddr).Msg("Unable connect to service, dropped...")
continue
} else {
statusOfServices[service.Type] = true
}
successCount++
}
log.Info().
Int("success", successCount).
Int("failed", len(services)-successCount).
Int("total", len(services)).
Msg("Service validation completed.")
}

View File

@@ -0,0 +1,48 @@
package grpc
import (
"context"
"git.solsynth.dev/hypernet/nexus/pkg/internal/cache"
"git.solsynth.dev/hypernet/nexus/pkg/internal/kv"
"git.solsynth.dev/hypernet/nexus/pkg/internal/mq"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/spf13/viper"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
func (v *Server) AllocMessageQueue(ctx context.Context, request *proto.AllocMqRequest) (*proto.AllocMqResponse, error) {
if mq.Kmq == nil {
return &proto.AllocMqResponse{IsSuccess: false}, status.Error(codes.Unavailable, "message queue wasn't configured")
}
return &proto.AllocMqResponse{
IsSuccess: true,
Addr: viper.GetString("mq.addr"),
}, nil
}
func (v *Server) AllocKv(ctx context.Context, request *proto.AllocKvRequest) (*proto.AllocKvResponse, error) {
if kv.Kv == nil {
return &proto.AllocKvResponse{IsSuccess: false}, status.Error(codes.Unavailable, "kv wasn't configured")
}
return &proto.AllocKvResponse{
IsSuccess: true,
Endpoints: viper.GetStringSlice("kv.endpoints"),
}, nil
}
func (v *Server) AllocCache(ctx context.Context, request *proto.AllocCacheRequest) (*proto.AllocCacheResponse, error) {
if cache.Rdb == nil {
return &proto.AllocCacheResponse{IsSuccess: false}, status.Error(codes.Unavailable, "cache wasn't configured")
}
return &proto.AllocCacheResponse{
IsSuccess: true,
Addr: viper.GetString("cache.addr"),
Password: viper.GetString("cache.password"),
Db: request.GetDb(),
}, nil
}

View File

@@ -0,0 +1,14 @@
package grpc
import (
"context"
"git.solsynth.dev/hypernet/nexus/pkg/internal/captcha"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
)
func (v *Server) CheckCaptcha(_ context.Context, req *proto.CheckCaptchaRequest) (*proto.CheckCaptchaResponse, error) {
return &proto.CheckCaptchaResponse{
IsValid: captcha.Validate(req.Token, req.RemoteIp),
}, nil
}

View File

@@ -1,9 +1,10 @@
package grpc
import (
directory2 "git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"net"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"google.golang.org/grpc/reflection"
@@ -15,8 +16,10 @@ import (
)
type Server struct {
proto.UnimplementedDatabaseControllerServer
proto.UnimplementedStreamControllerServer
proto.UnimplementedDatabaseServiceServer
proto.UnimplementedStreamServiceServer
proto.UnimplementedAllocatorServiceServer
proto.UnimplementedCaptchaServiceServer
health.UnimplementedHealthServer
srv *grpc.Server
@@ -27,10 +30,11 @@ func NewServer() *Server {
srv: grpc.NewServer(),
}
proto.RegisterServiceDirectoryServer(server.srv, &directory2.ServiceRpcServer{})
proto.RegisterCommandControllerServer(server.srv, &directory2.CommandRpcServer{})
proto.RegisterDatabaseControllerServer(server.srv, server)
proto.RegisterStreamControllerServer(server.srv, server)
proto.RegisterDirectoryServiceServer(server.srv, &directory.ServiceRpcServer{})
proto.RegisterDatabaseServiceServer(server.srv, server)
proto.RegisterStreamServiceServer(server.srv, server)
proto.RegisterAllocatorServiceServer(server.srv, server)
proto.RegisterCaptchaServiceServer(server.srv, server)
health.RegisterHealthServer(server.srv, server)
reflection.Register(server.srv)

View File

@@ -3,7 +3,8 @@ package grpc
import (
"context"
"fmt"
"git.solsynth.dev/hypernet/nexus/pkg/internal/http/ws"
"git.solsynth.dev/hypernet/nexus/pkg/internal/web/ws"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/samber/lo"
@@ -18,22 +19,24 @@ func (v *Server) CountStreamConnection(ctx context.Context, request *proto.Count
func (v *Server) PushStream(ctx context.Context, request *proto.PushStreamRequest) (*proto.PushStreamResponse, error) {
var cnt int
var success int
var successes []string
var errs []error
if request.UserId != nil {
cnt, success, errs = ws.WebsocketPush(uint(request.GetUserId()), request.GetBody())
cnt, successes, errs = ws.WebsocketPush(uint(request.GetUserId()), request.GetBody())
} else if request.ClientId != nil {
cnt, success, errs = ws.WebsocketPushDirect(request.GetClientId(), request.GetBody())
cnt, successes, errs = ws.WebsocketPushDirect(request.GetClientId(), request.GetBody())
} else {
return nil, fmt.Errorf("you must give one of the user id or client id")
}
success := len(successes)
if len(errs) > 0 {
// Partial fail
return &proto.PushStreamResponse{
IsAllSuccess: false,
AffectedCount: int64(success),
FailedCount: int64(cnt - success),
SuccessList: successes,
}, nil
} else if cnt > 0 && success == 0 {
// All fail
@@ -41,7 +44,7 @@ func (v *Server) PushStream(ctx context.Context, request *proto.PushStreamReques
}
return &proto.PushStreamResponse{
IsAllSuccess: true,
IsAllSuccess: cnt == success,
AffectedCount: int64(success),
FailedCount: int64(cnt - success),
}, nil
@@ -49,10 +52,10 @@ func (v *Server) PushStream(ctx context.Context, request *proto.PushStreamReques
func (v *Server) PushStreamBatch(ctx context.Context, request *proto.PushStreamBatchRequest) (*proto.PushStreamResponse, error) {
var cnt int
var success int
var successes []string
var errs []error
if len(request.UserId) != 0 {
cnt, success, errs = ws.WebsocketPushBatch(
cnt, successes, errs = ws.WebsocketPushBatch(
lo.Map(request.GetUserId(), func(item uint64, idx int) uint {
return uint(item)
},
@@ -62,10 +65,11 @@ func (v *Server) PushStreamBatch(ctx context.Context, request *proto.PushStreamB
if len(request.ClientId) != 0 {
cCnt, cSuccess, cErrs := ws.WebsocketPushBatchDirect(request.GetClientId(), request.GetBody())
cnt += cCnt
success += cSuccess
successes = append(successes, cSuccess...)
errs = append(errs, cErrs...)
}
success := len(successes)
if len(errs) > 0 {
// Partial fail
return &proto.PushStreamResponse{
@@ -79,8 +83,9 @@ func (v *Server) PushStreamBatch(ctx context.Context, request *proto.PushStreamB
}
return &proto.PushStreamResponse{
IsAllSuccess: true,
IsAllSuccess: cnt == success,
AffectedCount: int64(success),
FailedCount: int64(cnt - success),
SuccessList: successes,
}, nil
}

View File

@@ -1,67 +0,0 @@
package api
import (
"context"
"fmt"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
"google.golang.org/grpc/metadata"
"strings"
"time"
)
func invokeCommand(c *fiber.Ctx) error {
command := c.Params("command")
method := strings.ToLower(c.Method())
handler := directory.GetCommandHandler(command, method)
if handler == nil {
return fiber.NewError(fiber.StatusNotFound, "command not found")
}
conn, err := handler.GetGrpcConn()
if err != nil {
return fiber.NewError(fiber.StatusServiceUnavailable, "service unavailable")
}
log.Debug().Str("id", command).Str("method", method).Msg("Invoking command from HTTP Gateway...")
var meta []string
meta = append(meta, "client_id", "http-gateway")
meta = append(meta, "net.ip", c.IP())
meta = append(meta, "http.user_agent", c.Get(fiber.HeaderUserAgent))
for k, v := range c.GetReqHeaders() {
meta = append(
meta,
strings.ToLower(fmt.Sprintf("header.%s", strings.ReplaceAll(k, "-", "_"))),
strings.Join(v, "\n"),
)
}
for k, v := range c.Queries() {
meta = append(
meta,
strings.ToLower(fmt.Sprintf("query.%s", strings.ReplaceAll(k, "-", "_"))),
v,
)
}
ctx := metadata.AppendToOutgoingContext(c.Context(), meta...)
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
out, err := proto.NewCommandControllerClient(conn).SendCommand(ctx, &proto.CommandArgument{
Command: command,
Method: method,
Payload: c.Body(),
})
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} else {
c.Set(fiber.HeaderContentType, out.ContentType)
return c.Status(int(out.Status)).Send(out.Payload)
}
}

View File

@@ -1,41 +0,0 @@
package api
import (
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/proxy"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"strings"
)
func forwardService(c *fiber.Ctx) error {
serviceType := c.Params("service")
ogKeyword := serviceType
aliasingMap := viper.GetStringMapString("services.aliases")
if val, ok := aliasingMap[serviceType]; ok {
serviceType = val
}
service := directory.GetServiceInstanceByType(serviceType)
if service == nil || service.HttpAddr == nil {
return fiber.NewError(fiber.StatusNotFound, "service not found")
}
ogUrl := c.Request().URI().String()
url := c.OriginalURL()
url = strings.Replace(url, "/cgi/"+ogKeyword, "", 1)
url = *service.HttpAddr + url
log.Debug().
Str("from", ogUrl).
Str("to", url).
Str("service", serviceType).
Str("id", service.ID).
Msg("Forwarding request for service...")
return proxy.Do(c, url)
}

View File

@@ -1,30 +0,0 @@
package api
import (
"git.solsynth.dev/hypernet/nexus/pkg/internal/http/ws"
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2"
)
func MapAPIs(app *fiber.App) {
// Some built-in public-accessible APIs
wellKnown := app.Group("/.well-known").Name("Well Known")
{
wellKnown.Get("/", func(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusOK)
})
wellKnown.Get("/check-ip", getClientIP)
wellKnown.Get("/directory/services", listExistsService)
}
// Common websocket gateway
app.Use(func(c *fiber.Ctx) error {
/*if err := exts.EnsureAuthenticated(c); err != nil {
return err
}*/
return c.Next()
}).Get("/ws", websocket.New(ws.Listen))
app.All("/inv/:command", invokeCommand)
app.All("/cgi/:service/*", forwardService)
}

View File

@@ -1,54 +0,0 @@
package server
import (
"git.solsynth.dev/hypernet/nexus/pkg/internal/http/api"
"github.com/goccy/go-json"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/idempotency"
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
type HTTPApp struct {
app *fiber.App
}
func NewServer() *HTTPApp {
app := fiber.New(fiber.Config{
DisableStartupMessage: true,
EnableIPValidation: true,
ServerHeader: "Hypernet.Nexus",
AppName: "Hypernet.Nexus",
ProxyHeader: fiber.HeaderXForwardedFor,
JSONEncoder: json.Marshal,
JSONDecoder: json.Unmarshal,
BodyLimit: 512 * 1024 * 1024 * 1024, // 512 TiB
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
})
app.Use(idempotency.New())
app.Use(cors.New(cors.Config{
AllowCredentials: true,
AllowMethods: "GET,POST,HEAD,PUT,DELETE,PATCH",
AllowOriginsFunc: func(origin string) bool {
return true
},
}))
app.Use(logger.New(logger.Config{
Format: "${status} | ${latency} | ${method} ${path}\n",
Output: log.Logger,
}))
api.MapAPIs(app)
return &HTTPApp{app}
}
func (v *HTTPApp) Listen() {
if err := v.app.Listen(viper.GetString("bind")); err != nil {
log.Fatal().Err(err).Msg("An error occurred when starting server...")
}
}

View File

@@ -1,106 +0,0 @@
package ws
import (
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"math/rand"
"sync"
"git.solsynth.dev/hypernet/nexus/pkg/internal/models"
"github.com/gofiber/contrib/websocket"
)
var (
wsMutex sync.Mutex
wsConn = make(map[uint]map[uint64]*websocket.Conn)
)
func ClientRegister(user models.Account, conn *websocket.Conn) uint64 {
wsMutex.Lock()
if wsConn[user.ID] == nil {
wsConn[user.ID] = make(map[uint64]*websocket.Conn)
}
clientId := rand.Uint64()
wsConn[user.ID][clientId] = conn
wsMutex.Unlock()
directory.BroadcastEvent("ws.client.register", map[string]any{
"user": user.ID,
"id": clientId,
})
return clientId
}
func ClientUnregister(user models.Account, id uint64) {
wsMutex.Lock()
if wsConn[user.ID] == nil {
wsConn[user.ID] = make(map[uint64]*websocket.Conn)
}
delete(wsConn[user.ID], id)
wsMutex.Unlock()
directory.BroadcastEvent("ws.client.unregister", map[string]any{
"user": user.ID,
"id": id,
})
}
func ClientCount(uid uint) int {
return len(wsConn[uid])
}
func WebsocketPush(uid uint, body []byte) (count int, success int, errs []error) {
for _, conn := range wsConn[uid] {
if err := conn.WriteMessage(1, body); err != nil {
errs = append(errs, err)
} else {
success++
}
count++
}
return
}
func WebsocketPushDirect(clientId uint64, body []byte) (count int, success int, errs []error) {
for _, m := range wsConn {
if conn, ok := m[clientId]; ok {
if err := conn.WriteMessage(1, body); err != nil {
errs = append(errs, err)
} else {
success++
}
count++
}
}
return
}
func WebsocketPushBatch(uidList []uint, body []byte) (count int, success int, errs []error) {
for _, uid := range uidList {
for _, conn := range wsConn[uid] {
if err := conn.WriteMessage(1, body); err != nil {
errs = append(errs, err)
} else {
success++
}
count++
}
}
return
}
func WebsocketPushBatchDirect(clientIdList []uint64, body []byte) (count int, success int, errs []error) {
for _, clientId := range clientIdList {
for _, m := range wsConn {
if conn, ok := m[clientId]; ok {
if err := conn.WriteMessage(1, body); err != nil {
errs = append(errs, err)
} else {
success++
}
count++
}
}
}
return
}

View File

@@ -1,85 +0,0 @@
package ws
import (
"git.solsynth.dev/hypernet/nexus/pkg/internal/models"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"github.com/gofiber/contrib/websocket"
jsoniter "github.com/json-iterator/go"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
func Listen(c *websocket.Conn) {
user := c.Locals("user").(models.Account)
// Push connection
clientId := ClientRegister(user, c)
log.Debug().
Uint("user", user.ID).
Uint64("clientId", clientId).
Msg("New websocket connection established...")
// Event loop
var mt int
var data []byte
var err error
var packet nex.WebSocketPackage
for {
if mt, data, err = c.ReadMessage(); err != nil {
break
} else if err := jsoniter.Unmarshal(data, &packet); err != nil {
_ = c.WriteMessage(mt, nex.WebSocketPackage{
Action: "error",
Message: "unable to unmarshal your command, requires json request",
}.Marshal())
continue
}
aliasingMap := viper.GetStringMapString("services.aliases")
if val, ok := aliasingMap[packet.Endpoint]; ok {
packet.Endpoint = val
}
/*
service := directory.GetServiceInstanceByType(packet.Endpoint)
if service == nil {
_ = c.WriteMessage(mt, nex.NetworkPackage{
Action: "error",
Message: "service not found",
}.Marshal())
continue
}
pc, err := service.GetGrpcConn()
if err != nil {
_ = c.WriteMessage(mt, nex.NetworkPackage{
Action: "error",
Message: fmt.Sprintf("unable to connect to service: %v", err.Error()),
}.Marshal())
continue
}
sc := proto.NewStreamControllerClient(pc)
_, err = sc.EmitStreamEvent(context.Background(), &proto.StreamEventRequest{
Event: packet.Action,
UserId: uint64(user.ID),
ClientId: uint64(clientId),
Payload: packet.RawPayload(),
})
if err != nil {
_ = c.WriteMessage(mt, nex.NetworkPackage{
Action: "error",
Message: fmt.Sprintf("unable send message to service: %v", err.Error()),
}.Marshal())
continue
}*/
}
// Pop connection
ClientUnregister(user, clientId)
log.Debug().
Uint("user", user.ID).
Uint64("clientId", clientId).
Msg("A websocket connection disconnected...")
}

37
pkg/internal/kv/etcd.go Normal file
View File

@@ -0,0 +1,37 @@
package kv
import (
"context"
"fmt"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
clientv3 "go.etcd.io/etcd/client/v3"
"time"
)
var Kv *clientv3.Client
func ConnectEtcd(endpoints []string) error {
conn, err := clientv3.New(clientv3.Config{
Endpoints: endpoints,
DialTimeout: 10 * time.Second,
})
if err != nil {
return err
}
var status []bool
for _, endpoint := range endpoints {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
_, err := conn.Status(ctx, endpoint)
if err != nil {
log.Warn().Str("endpoint", endpoint).Err(err).Msg("An KV endpoint is not available...")
}
status = append(status, err == nil)
cancel()
}
if len(lo.Filter(status, func(s bool, _ int) bool { return s })) == 0 {
return fmt.Errorf("unable to connect to all KV endpoints")
}
Kv = conn
return err
}

View File

@@ -2,4 +2,5 @@ package pkg
const (
AppVersion = "1.0.0"
ApiLevel = 10
)

16
pkg/internal/mq/nats.go Normal file
View File

@@ -0,0 +1,16 @@
package mq
import "github.com/nats-io/nats.go"
var Kmq *nats.Conn
func ConnectNats(in string) error {
nc, err := nats.Connect(in)
if err != nil {
return err
} else {
Kmq = nc
}
return nil
}

View File

@@ -0,0 +1,154 @@
package watchtower
import (
"bytes"
"fmt"
"os"
"os/exec"
"os/user"
"path/filepath"
"strings"
"time"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
var dbWatchlist []string
func AddWatchDb(dsn string) {
dbWatchlist = append(dbWatchlist, dsn)
}
func BackupDb() error {
backupPath := viper.GetString("watchtower.database_backups")
if err := os.MkdirAll(backupPath, 0775); err != nil {
return fmt.Errorf("failed to create backup path: %v", err)
}
outFile := filepath.Join(
backupPath,
fmt.Sprintf("watchtower_db_backup_%s", time.Now().Format("2006-01-02_15:04:05")),
)
// Reading config
var password string
var username string
var host string
var port string
dsnParts := strings.Split(viper.GetString("database.dsn"), " ")
for _, part := range dsnParts {
if strings.HasPrefix(part, "password=") {
password = strings.Replace(part, "password=", "", 1)
} else if strings.HasPrefix(part, "user=") {
username = strings.Replace(part, "user=", "", 1)
} else if strings.HasPrefix(part, "host=") {
host = strings.Replace(part, "host=", "", 1)
} else if strings.HasPrefix(part, "port=") {
port = strings.Replace(part, "port=", "", 1)
}
}
// Creating ~/.pgpass
usr, err := user.Current()
if err != nil {
return fmt.Errorf("unable to get current user: %v", err)
}
homeDir := usr.HomeDir
pgpassFile := filepath.Join(homeDir, ".pgpass")
pgpassString := fmt.Sprintf("%s:%s:%s:%s:%s\n", host, port, "*", username, password)
// Open the .pgpass pgpass for writing (create if it doesn't exist)
pgpass, err := os.OpenFile(pgpassFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) // Set file permissions to 0600
if err != nil {
log.Error().Err(err).Str("path", pgpassFile).Msg("Failed to open .pgpass file...")
return fmt.Errorf("failed to open .pgpass file: %v", err)
}
if _, err = pgpass.WriteString(pgpassString); err != nil {
log.Error().Err(err).Msg("Failed to write to .pgpass file...")
return fmt.Errorf("failed to write to .pgpass file: %v", err)
} else {
pgpass.Close()
}
log.Info().Msg("Wrote to .pgpass file...")
// Backing up
log.Info().
Str("password", password).Str("user", username).
Str("host", host).Str("port", port).
Msg("Starting backup database...")
cmd := exec.Command("pg_dumpall",
"-h", host,
"-p", port,
"-U", username,
"-f", outFile,
"-w",
)
cmd.Env = os.Environ()
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
start := time.Now()
if err := cmd.Run(); err != nil {
log.Error().
Err(err).Str("stdout", stdout.String()).Str("stderr", stderr.String()).
Msg("Failed to backup the database...")
return err
}
took := time.Since(start)
log.Info().
Str("out", outFile).Dur("took", took).
Str("stdout", stdout.String()).Str("stderr", stderr.String()).
Msg("Backed up database successfully!")
return nil
}
func CleanDb(dsn string) error {
conn, err := gorm.Open(postgres.Open(dsn))
if err != nil {
return fmt.Errorf("failed to open database: %v", err)
}
var tables []string
if err := conn.Raw("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'").Scan(&tables).Error; err != nil {
return fmt.Errorf("failed to scan tables: %v", err)
}
deadline := time.Now().Add(-7 * 24 * time.Hour) // 7 days before
for _, table := range tables {
sql := fmt.Sprintf("DELETE FROM %s WHERE deleted_at < ?", table)
if tx := conn.Raw(sql, deadline); tx.Error != nil {
log.Warn().Err(err).Str("table", table).Str("dsn", dsn).Msg("Unable to clean soft deleted records in this table...")
} else {
log.Info().Str("table", table).Str("dsn", dsn).Int64("rows", tx.RowsAffected).Msg("Cleaned soft deleted records in this table...")
}
}
return nil
}
func CleanAllDb() {
for _, database := range dbWatchlist {
if err := CleanDb(database); err != nil {
log.Error().Err(err).Msg("Failed to clean up a database...")
}
}
}
func RunDbMaintenance() {
if err := BackupDb(); err != nil {
return
}
CleanAllDb()
}

View File

@@ -0,0 +1,25 @@
package api
import (
"git.solsynth.dev/hypernet/nexus/pkg/internal/captcha"
"git.solsynth.dev/hypernet/nexus/pkg/internal/web/exts"
"github.com/gofiber/fiber/v2"
)
func renderCaptcha(c *fiber.Ctx) error {
return c.Render("captcha", captcha.GetTemplateData())
}
func validateCaptcha(c *fiber.Ctx) error {
var body struct {
CaptchaToken string `json:"captcha_tk"`
}
if err := exts.BindAndValidate(c, &body); err != nil {
return err
}
if !captcha.Validate(body.CaptchaToken, c.IP()) {
return c.SendStatus(fiber.StatusNotAcceptable)
}
return c.SendStatus(fiber.StatusOK)
}

View File

@@ -1,15 +1,15 @@
package api
import (
directory2 "git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"github.com/gofiber/fiber/v2"
"github.com/samber/lo"
)
func listExistsService(c *fiber.Ctx) error {
services := directory2.ListServiceInstance()
services := directory.ListServiceInstance()
return c.JSON(lo.Map(services, func(item *directory2.ServiceInstance, index int) map[string]any {
return c.JSON(lo.Map(services, func(item *directory.ServiceInstance, index int) map[string]any {
return map[string]any{
"id": item.ID,
"type": item.Type,

View File

@@ -0,0 +1,68 @@
package api
import (
"fmt"
"strings"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/proxy"
"github.com/spf13/viper"
"github.com/valyala/fasthttp"
)
func forwardWebfinger(c *fiber.Ctx) error {
service := directory.GetServiceInstanceByType("co")
if service == nil || service.HttpAddr == nil {
return fiber.ErrNotFound
}
url := c.OriginalURL()
url = strings.Replace(url, "/.well-known", "", 1)
url = *service.HttpAddr + url
if tk, ok := c.Locals("nex_token").(string); ok {
c.Request().Header.Set(fiber.HeaderAuthorization, fmt.Sprintf("Bearer %s", tk))
} else {
c.Request().Header.Del(fiber.HeaderAuthorization)
}
return proxy.Do(c, url, &fasthttp.Client{
NoDefaultUserAgentHeader: true,
DisablePathNormalizing: true,
StreamResponseBody: true,
})
}
func forwardService(c *fiber.Ctx) error {
serviceType := c.Params("service")
ogKeyword := serviceType
aliasingMap := viper.GetStringMapString("services.aliases")
if val, ok := aliasingMap[serviceType]; ok {
serviceType = val
}
service := directory.GetServiceInstanceByType(serviceType)
if service == nil || service.HttpAddr == nil {
return fiber.NewError(fiber.StatusNotFound, "service not found")
}
url := c.OriginalURL()
url = strings.Replace(url, "/cgi/"+ogKeyword, "", 1)
url = *service.HttpAddr + url
if tk, ok := c.Locals("nex_token").(string); ok {
c.Request().Header.Set(fiber.HeaderAuthorization, fmt.Sprintf("Bearer %s", tk))
} else {
c.Request().Header.Del(fiber.HeaderAuthorization)
}
return proxy.Do(c, url, &fasthttp.Client{
NoDefaultUserAgentHeader: true,
DisablePathNormalizing: true,
StreamResponseBody: true,
})
}

View File

@@ -0,0 +1,59 @@
package api
import (
pkg "git.solsynth.dev/hypernet/nexus/pkg/internal"
"git.solsynth.dev/hypernet/nexus/pkg/internal/auth"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"git.solsynth.dev/hypernet/nexus/pkg/internal/web/ws"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/proxy"
)
func MapControllers(app *fiber.App) {
app.Get("/meet/:channel", renderMeetRoom)
app.Get("/captcha", renderCaptcha)
app.Post("/captcha", validateCaptcha)
app.Get("/check-ip", getClientIP)
app.Get("/", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"api_level": pkg.ApiLevel,
"version": pkg.AppVersion,
"status": true,
})
})
app.Get("/directory/status", getServicesStatus)
app.Get("/directory/services", listExistsService)
// Some built-in public-accessible APIs
wellKnown := app.Group("/.well-known").Name("Well Known")
{
wellKnown.Get("/webfinger", forwardWebfinger) // Forward webfinger to Interactive
wellKnown.Get("/openid-configuration", func(c *fiber.Ctx) error {
service := directory.GetServiceInstanceByType(nex.ServiceTypeAuth)
if service == nil || service.HttpAddr == nil {
return fiber.ErrNotFound
}
return proxy.Do(c, *service.HttpAddr+"/.well-known/openid-configuration")
})
wellKnown.Get("/jwks", func(c *fiber.Ctx) error {
service := directory.GetServiceInstanceByType(nex.ServiceTypeAuth)
if service == nil || service.HttpAddr == nil {
return fiber.ErrNotFound
}
return proxy.Do(c, *service.HttpAddr+"/.well-known/jwks")
})
}
// WatchTower administration APIs
wt := app.Group("/wt").Name("WatchTower").Use(auth.ValidatorMiddleware)
{
wt.Post("/maintenance/database", watchRunDbMaintenance)
}
// Common websocket gateway
app.Get("/ws", auth.ValidatorMiddleware, websocket.New(ws.Listen))
app.All("/cgi/:service/*", forwardService)
}

View File

@@ -0,0 +1,55 @@
package api
import (
"fmt"
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"github.com/gofiber/fiber/v2"
"github.com/spf13/viper"
"strings"
)
type meetRoomArgs struct {
RoomName string `json:"room_name"`
User meetRoomUser `json:"user"`
}
type meetRoomUser struct {
Avatar string `json:"avatar"`
Nick string `json:"nick"`
}
func renderMeetRoom(c *fiber.Ctx) error {
if err := sec.EnsureAuthenticated(c); err != nil {
return err
}
user := c.Locals("nex_user").(*sec.UserInfo)
channel := c.Params("channel")
var nick string
if val, ok := user.Metadata["nick"].(string); ok {
nick = val
} else {
nick = user.Name
}
var avatar string
if val, ok := user.Metadata["avatar"].(string); ok {
if strings.HasPrefix(val, "http") {
avatar = val
} else {
endpoint := viper.GetString("resources_endpoint")
avatar = fmt.Sprintf("%s/attachments/%s", endpoint, val)
}
avatar = fmt.Sprintf("\"%s\"", avatar) // Make the avatar a string to embed into the js
} else {
avatar = "undefined"
}
return c.Render("meet", meetRoomArgs{
RoomName: fmt.Sprintf("%s-%s", "sn-chat", channel),
User: meetRoomUser{
Avatar: avatar,
Nick: nick,
},
})
}

View File

@@ -0,0 +1,10 @@
package api
import (
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"github.com/gofiber/fiber/v2"
)
func getServicesStatus(c *fiber.Ctx) error {
return c.JSON(directory.GetServiceStatus())
}

View File

@@ -0,0 +1,15 @@
package api
import (
"git.solsynth.dev/hypernet/nexus/pkg/internal/watchtower"
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"github.com/gofiber/fiber/v2"
)
func watchRunDbMaintenance(c *fiber.Ctx) error {
if err := sec.EnsureGrantedPerm(c, "AdminOperateWatchTower", true); err != nil {
return err
}
go watchtower.RunDbMaintenance()
return c.SendStatus(fiber.StatusOK)
}

View File

@@ -0,0 +1,34 @@
package web
import (
"bufio"
"os"
"github.com/rs/zerolog/log"
)
var ipBlocklist []string
func AddBlockIP(ip string) {
ipBlocklist = append(ipBlocklist, ip)
}
func ParseBlockIPList(path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
ipBlocklist = append(ipBlocklist, scanner.Text())
}
if err := scanner.Err(); err != nil {
return err
}
log.Info().Int("count", len(ipBlocklist)).Msg("Block IP list parsed successfully.")
return nil
}

View File

@@ -0,0 +1,89 @@
package web
import (
"time"
"git.solsynth.dev/hypernet/nexus/pkg/internal/auth"
"git.solsynth.dev/hypernet/nexus/pkg/internal/web/api"
"github.com/goccy/go-json"
"github.com/gofiber/contrib/fiberzerolog"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/idempotency"
"github.com/gofiber/fiber/v2/middleware/limiter"
"github.com/gofiber/template/html/v2"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
"github.com/spf13/viper"
)
type WebApp struct {
app *fiber.App
}
func NewServer() *WebApp {
engine := html.New(viper.GetString("templates_dir"), ".tmpl")
app := fiber.New(fiber.Config{
DisableStartupMessage: true,
EnableIPValidation: true,
ServerHeader: "HyperNet.Nexus",
AppName: "HyperNet.Nexus",
ProxyHeader: fiber.HeaderXForwardedFor,
JSONEncoder: json.Marshal,
JSONDecoder: json.Unmarshal,
BodyLimit: 512 * 1024 * 1024 * 1024, // 512 TiB
ReadBufferSize: 5 * 1024 * 1024, // 5MB for large JWT
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
Views: engine,
})
app.Use(fiberzerolog.New(fiberzerolog.Config{
Logger: &log.Logger,
}))
app.Use(idempotency.New())
app.Use(cors.New(cors.Config{
AllowCredentials: true,
AllowMethods: "GET,POST,HEAD,PUT,DELETE,PATCH",
AllowOriginsFunc: func(origin string) bool {
return true
},
}))
app.Use(func(c *fiber.Ctx) error {
if lo.Contains(ipBlocklist, c.IP()) {
return fiber.NewError(fiber.StatusForbidden, "your ip has been listed in the blacklist")
}
return c.Next()
})
app.Use(limiter.New(limiter.Config{
Max: viper.GetInt("rate_limit"),
Expiration: 60 * time.Second,
LimiterMiddleware: limiter.SlidingWindow{},
Next: func(c *fiber.Ctx) bool {
return lo.Contains([]string{"POST", "PUT", "DELETE", "PATCH"}, c.Method())
},
}))
app.Use(limiter.New(limiter.Config{
Max: viper.GetInt("rate_limit_advance"),
Expiration: 60 * time.Second,
LimiterMiddleware: limiter.SlidingWindow{},
Next: func(c *fiber.Ctx) bool {
return lo.Contains([]string{"GET", "HEAD", "OPTIONS", "CONNECT", "TRACE"}, c.Method())
},
}))
app.Use(auth.ContextMiddleware)
api.MapControllers(app)
return &WebApp{app}
}
func (v *WebApp) Listen() {
if err := v.app.Listen(viper.GetString("bind")); err != nil {
log.Fatal().Err(err).Msg("An error occurred when starting server...")
}
}

View File

@@ -0,0 +1,127 @@
package ws
import (
"fmt"
"sync"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
"github.com/gofiber/contrib/websocket"
)
var (
wsMutex sync.Mutex
wsConn = make(map[uint]map[string]*websocket.Conn)
)
func ClientRegister(user sec.UserInfo, conn *websocket.Conn) (string, error) {
wsMutex.Lock()
if wsConn[user.ID] == nil {
wsConn[user.ID] = make(map[string]*websocket.Conn)
}
var clientId string
if userDefinedId := conn.Query("clientId"); len(userDefinedId) > 0 && len(userDefinedId) <= 16 {
clientId = userDefinedId
} else {
clientId = uuid.NewString()
}
if _, ok := wsConn[user.ID][clientId]; ok {
return clientId, fmt.Errorf("client already conncted")
}
wsConn[user.ID][clientId] = conn
wsMutex.Unlock()
log.Debug().
Str("client_id", clientId).
Uint("user_id", user.ID).
Msg("An client connected to stream endpoint...")
_ = directory.BroadcastEvent("ws.client.register", map[string]any{
"user": user.ID,
"id": clientId,
})
return clientId, nil
}
func ClientUnregister(user sec.UserInfo, id string) {
wsMutex.Lock()
if wsConn[user.ID] == nil {
wsConn[user.ID] = make(map[string]*websocket.Conn)
}
delete(wsConn[user.ID], id)
wsMutex.Unlock()
log.Debug().
Str("client_id", id).
Uint("user_id", user.ID).
Msg("An client disconnected from stream endpoint...")
_ = directory.BroadcastEvent("ws.client.unregister", map[string]any{
"user": user.ID,
"id": id,
})
}
func ClientCount(uid uint) int {
return len(wsConn[uid])
}
func WebsocketPush(uid uint, body []byte) (count int, successes []string, errs []error) {
for _, conn := range wsConn[uid] {
if err := conn.WriteMessage(1, body); err != nil {
errs = append(errs, err)
} else {
successes = append(successes, fmt.Sprintf("%d", uid))
}
count++
}
return
}
func WebsocketPushDirect(clientId string, body []byte) (count int, successes []string, errs []error) {
for _, m := range wsConn {
if conn, ok := m[clientId]; ok {
if err := conn.WriteMessage(1, body); err != nil {
errs = append(errs, err)
} else {
successes = append(successes, clientId)
}
count++
}
}
return
}
func WebsocketPushBatch(uidList []uint, body []byte) (count int, successes []string, errs []error) {
for _, uid := range uidList {
for _, conn := range wsConn[uid] {
if err := conn.WriteMessage(1, body); err != nil {
errs = append(errs, err)
} else {
successes = append(successes, fmt.Sprintf("%d", uid))
}
count++
}
}
return
}
func WebsocketPushBatchDirect(clientIdList []string, body []byte) (count int, successes []string, errs []error) {
for _, clientId := range clientIdList {
for _, m := range wsConn {
if conn, ok := m[clientId]; ok {
if err := conn.WriteMessage(1, body); err != nil {
errs = append(errs, err)
} else {
successes = append(successes, clientId)
}
count++
}
}
}
return
}

89
pkg/internal/web/ws/ws.go Normal file
View File

@@ -0,0 +1,89 @@
package ws
import (
"context"
"fmt"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/gofiber/contrib/websocket"
jsoniter "github.com/json-iterator/go"
"github.com/samber/lo"
)
func Listen(c *websocket.Conn) {
user, ok := c.Locals("nex_user").(*sec.UserInfo)
if !ok {
_ = c.WriteMessage(1, nex.WebSocketPackage{
Action: "error",
Message: "unauthorized",
}.Marshal())
c.Close()
return
}
// Push connection
var err error
clientId, err := ClientRegister(*user, c)
if err != nil {
_ = c.WriteMessage(1, nex.WebSocketPackage{
Action: "error",
Message: "client with this id already connected",
}.Marshal())
c.Close()
return
}
// Event loop
var mt int
var data []byte
var packet nex.WebSocketPackage
for {
if mt, data, err = c.ReadMessage(); err != nil {
break
} else if err := jsoniter.Unmarshal(data, &packet); err != nil {
_ = c.WriteMessage(mt, nex.WebSocketPackage{
Action: "error",
Message: "unable to unmarshal your command, requires json request",
}.Marshal())
continue
}
service := directory.GetServiceInstanceByType(packet.Endpoint)
if service == nil {
_ = c.WriteMessage(mt, nex.WebSocketPackage{
Action: "error",
Message: "service not found",
}.Marshal())
continue
}
pc, err := service.GetGrpcConn()
if err != nil {
_ = c.WriteMessage(mt, nex.WebSocketPackage{
Action: "error",
Message: fmt.Sprintf("unable to connect to service: %v", err.Error()),
}.Marshal())
continue
}
sc := proto.NewStreamServiceClient(pc)
_, err = sc.PushStream(context.Background(), &proto.PushStreamRequest{
UserId: lo.ToPtr(uint64(user.ID)),
ClientId: lo.ToPtr(clientId),
Body: packet.Marshal(),
})
if err != nil {
_ = c.WriteMessage(mt, nex.WebSocketPackage{
Action: "error",
Message: fmt.Sprintf("unable send message to service: %v", err.Error()),
}.Marshal())
continue
}
}
// Pop connection
ClientUnregister(*user, clientId)
}

View File

@@ -2,13 +2,21 @@ package main
import (
"fmt"
"git.solsynth.dev/hypernet/nexus/pkg/internal/database"
"git.solsynth.dev/hypernet/nexus/pkg/internal/http"
"github.com/fatih/color"
"os"
"os/signal"
"syscall"
"git.solsynth.dev/hypernet/nexus/pkg/internal/auth"
"git.solsynth.dev/hypernet/nexus/pkg/internal/cache"
"git.solsynth.dev/hypernet/nexus/pkg/internal/database"
"git.solsynth.dev/hypernet/nexus/pkg/internal/directory"
"git.solsynth.dev/hypernet/nexus/pkg/internal/kv"
"git.solsynth.dev/hypernet/nexus/pkg/internal/mq"
"git.solsynth.dev/hypernet/nexus/pkg/internal/watchtower"
"git.solsynth.dev/hypernet/nexus/pkg/internal/web"
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
"github.com/fatih/color"
pkg "git.solsynth.dev/hypernet/nexus/pkg/internal"
"git.solsynth.dev/hypernet/nexus/pkg/internal/grpc"
"github.com/robfig/cron/v3"
@@ -43,9 +51,37 @@ func main() {
// Load settings
if err := viper.ReadInConfig(); err != nil {
log.Panic().Err(err).Msg("An error occurred when loading settings.")
} else if err := web.ParseBlockIPList(viper.GetString("ip_block_path")); err != nil {
log.Error().Err(err).Msg("An error occurred when parsing block IP list.")
}
// Connect to kv (etcd)
log.Info().Msg("Connecting to kv (etcd)...")
if err := kv.ConnectEtcd(viper.GetStringSlice("kv.endpoints")); err != nil {
log.Error().Err(err).Msg("An error occurred when connecting to kv (etcd), please check your configuration in kv section.")
log.Fatal().Msg("Kv is required for service discovery and directory feature, cannot be disabled.")
} else {
log.Info().Msg("Connected to kv (etcd)!")
}
// Connect to message queue (nats)
log.Info().Msg("Connecting to MQ (nats)...")
if err := mq.ConnectNats(viper.GetString("mq.addr")); err != nil {
log.Error().Err(err).Msg("An error occurred when connecting to MQ (nats). MQ related feature will be disabled.")
} else {
log.Info().Msg("Connected to MQ (nats)!")
}
// Connect to cache (redis)
log.Info().Msg("Connecting to cache (redis)...")
if err := cache.ConnectRedis(viper.GetString("cache.addr"), viper.GetString("cache.password"), 0); err != nil {
log.Error().Err(err).Msg("An error occurred when connecting to cache (redis). Cache related features will be disabled.")
} else {
log.Info().Msg("Connected to cache (redis)!")
}
// Connect to database
log.Info().Msg("Connecting to database...")
if db, err := database.Connect(viper.GetString("database.dsn")); err != nil {
log.Error().Err(err).Msg("An error occurred when connecting to database. Database related features will be disabled.")
} else {
@@ -55,18 +91,44 @@ func main() {
log.Error().Err(err).Msg("An error occurred when querying database version. Database related features will be disabled.")
database.Kdb = nil
} else {
log.Info().Str("version", version).Msg("Connected to database")
log.Info().Str("version", version).Msg("Connected to database!")
}
}
// Read the public key for jwt
if reader, err := sec.NewJwtReader(viper.GetString("security.public_key")); err != nil {
log.Error().Err(err).Msg("An error occurred when reading public key for jwt. Authentication related features will be disabled.")
} else {
auth.JReader = reader
log.Info().Msg("Jwt public key loaded.")
}
if reader, err := sec.NewInternalTokenReader(viper.GetString("security.internal_public_key")); err != nil {
log.Error().Err(err).Msg("An error occurred when reading internal public key for jwt. Authentication related features will be disabled.")
} else {
auth.IReader = reader
log.Info().Msg("Internal jwt public key loaded.")
}
if writer, err := sec.NewInternalTokenWriter(viper.GetString("security.internal_private_key")); err != nil {
log.Error().Err(err).Msg("An error occurred when reading internal private key for jwt. Authentication related features will be disabled.")
} else {
auth.IWriter = writer
log.Info().Msg("Internal jwt private key loaded.")
}
// Post-boot actions
go directory.ValidateServices()
// Server
go server.NewServer().Listen()
go web.NewServer().Listen()
// Grpc Server
go grpc.NewServer().Listen()
// Configure timed tasks
quartz := cron.New(cron.WithLogger(cron.VerbosePrintfLogger(&log.Logger)))
quartz.AddFunc("@midnight", watchtower.RunDbMaintenance)
quartz.AddFunc("@every 5m", directory.ValidateServices)
quartz.Start()
// Messages

19
pkg/nex/README.md Normal file
View File

@@ -0,0 +1,19 @@
# Nex
The Hypernet.Nexus development SDK.
Defined the useful functions and ways to handle data for both server side and client.
## Parts
### Nex.Cruda
Create Read Update Delete Accelerator, aka. Cruda.
Cruda will help you to build a simplified database access layer based on the command system in nexus.
### Nex.Sec
The security part of nexus, including signing and validating the tokens and much more.
### Nex.Rx
The reactive part of nexus, such as streaming events, and message queues stuff.

50
pkg/nex/allocator.go Normal file
View File

@@ -0,0 +1,50 @@
package nex
import (
"context"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/redis/go-redis/v9"
)
type AllocatableResourceType = string
const (
AllocatableResourceMq = AllocatableResourceType("mq")
AllocatableResourceKv = AllocatableResourceType("kv")
AllocatableResourceCache = AllocatableResourceType("cache")
)
func (v *Conn) AllocResource(t AllocatableResourceType) any {
switch t {
case AllocatableResourceMq:
conn := v.GetNexusGrpcConn()
resp, err := proto.NewAllocatorServiceClient(conn).AllocMessageQueue(context.Background(), &proto.AllocMqRequest{})
if err != nil || !resp.IsSuccess {
return nil
}
return resp.Addr
case AllocatableResourceKv:
conn := v.GetNexusGrpcConn()
resp, err := proto.NewAllocatorServiceClient(conn).AllocKv(context.Background(), &proto.AllocKvRequest{})
if err != nil || !resp.IsSuccess {
return nil
}
return resp.Endpoints
case AllocatableResourceCache:
conn := v.GetNexusGrpcConn()
resp, err := proto.NewAllocatorServiceClient(conn).AllocCache(context.Background(), &proto.AllocCacheRequest{
Db: 0,
})
if err != nil || !resp.IsSuccess {
return nil
}
return redis.NewClient(&redis.Options{
Addr: resp.GetAddr(),
Password: resp.GetPassword(),
DB: int(resp.GetDb()),
})
default:
return nil
}
}

View File

@@ -0,0 +1,9 @@
package cachekit
import (
redis_store "github.com/eko/gocache/store/redis/v4"
)
func (c *Conn) GoCache() *redis_store.RedisStore {
return redis_store.NewRedis(c.Rd)
}

View File

@@ -0,0 +1,15 @@
package cachekit
import "fmt"
// Those constants are used to directly get the cached data from redis
// Formatted like {prefix}#{key}
const (
DAAttachment = "attachment"
DAUser = "account"
DARealm = "realm"
)
func FKey(prefix string, key any) string {
return fmt.Sprintf("%s#%v", prefix, key)
}

75
pkg/nex/cachekit/io.go Normal file
View File

@@ -0,0 +1,75 @@
package cachekit
import (
"fmt"
"time"
"github.com/eko/gocache/lib/v4/cache"
"github.com/eko/gocache/lib/v4/store"
"github.com/goccy/go-json"
)
// The functions below are operating the redis via the gocache
// Provide a advanced tagging experience
// At the same time, the advanced cache using client side marshaling to handle the advance data types
func Set[T any](c *Conn, key string, value T, ttl time.Duration, tags ...string) error {
raw, err := json.Marshal(value)
if err != nil {
return fmt.Errorf("unable to marshal value during caching: %v", err)
}
ctx, cancel := c.withTimeout()
defer cancel()
cm := cache.New[string](c.GoCache())
return cm.Set(ctx, key, string(raw), store.WithTags(tags), store.WithExpiration(ttl))
}
// SetKA stands for Set Keep Alive
// Don't set a TTL for the value set via this function
func SetKA[T any](c *Conn, key string, value T, tags ...string) error {
raw, err := json.Marshal(value)
if err != nil {
return fmt.Errorf("unable to marshal value during caching: %v", err)
}
ctx, cancel := c.withTimeout()
defer cancel()
cm := cache.New[string](c.GoCache())
return cm.Set(ctx, key, string(raw), store.WithTags(tags))
}
func Get[T any](c *Conn, key string) (T, error) {
var out T
ctx, cancel := c.withTimeout()
defer cancel()
cm := cache.New[string](c.GoCache())
raw, err := cm.Get(ctx, key)
if err != nil {
return out, err
}
if err := json.Unmarshal([]byte(raw), &out); err != nil {
return out, fmt.Errorf("unable to unmarshal value during caching: %v", err)
}
return out, nil
}
func Delete(c *Conn, key string) error {
ctx, cancel := c.withTimeout()
defer cancel()
cm := cache.New[[]byte](c.GoCache())
return cm.Delete(ctx, key)
}
func DeleteByTags(c *Conn, tags ...string) error {
if len(tags) == 0 {
return nil
}
ctx, cancel := c.withTimeout()
defer cancel()
cm := cache.New[[]byte](c.GoCache())
return cm.Invalidate(ctx, store.WithInvalidateTags(tags))
}

View File

@@ -0,0 +1,54 @@
package cachekit
import "time"
// The functions below are directly using the redis connection to operaete the redis
// Set stores a key-value pair in Redis with an optional expiration time
func (c *Conn) RSet(key string, value any, ttl time.Duration) error {
ctx, cancel := c.withTimeout()
defer cancel()
return c.Rd.Set(ctx, key, value, ttl).Err()
}
// Get retrieves a value from Redis by key
func (c *Conn) RGet(key string) (string, error) {
ctx, cancel := c.withTimeout()
defer cancel()
return c.Rd.Get(ctx, key).Result()
}
// Delete removes a key from Redis
func (c *Conn) RDelete(key string) error {
ctx, cancel := c.withTimeout()
defer cancel()
return c.Rd.Del(ctx, key).Err()
}
// Exists checks if a key exists in Redis
func (c *Conn) RExists(key string) (bool, error) {
ctx, cancel := c.withTimeout()
defer cancel()
exists, err := c.Rd.Exists(ctx, key).Result()
if err != nil {
return false, err
}
return exists > 0, nil
}
// ClearCacheByPrefix deletes all keys matching a given prefix
func (c *Conn) RDeleteByPrefix(prefix string) error {
ctx, cancel := c.withTimeout()
defer cancel()
iter := c.Rd.Scan(ctx, 0, prefix+"*", 0).Iterator()
for iter.Next(ctx) {
if err := c.Rd.Del(ctx, iter.Val()).Err(); err != nil {
return err
}
}
if err := iter.Err(); err != nil {
return err
}
return nil
}

56
pkg/nex/cachekit/rdb.go Normal file
View File

@@ -0,0 +1,56 @@
package cachekit
import (
"context"
"fmt"
"sync"
"time"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"github.com/redis/go-redis/v9"
)
// The global variable below is used to keep there will only be one redis client exist in a single instance
// Prevent if other DirectAccess™ SDK creating too many redis clients
// And able to recreate the conn with different options
var (
rdc *redis.Client
rdl sync.Mutex
)
type Conn struct {
n *nex.Conn
Rd *redis.Client
Timeout time.Duration
}
func NewConn(conn *nex.Conn, timeout time.Duration) (*Conn, error) {
rdl.Lock()
defer rdl.Unlock()
c := &Conn{
n: conn,
Timeout: timeout,
}
if rdc != nil {
c.Rd = rdc
return c, nil
}
rdb := conn.AllocResource(nex.AllocatableResourceCache)
if rdb == nil {
return nil, fmt.Errorf("unable to allocate resource: cache")
} else if client, ok := rdb.(*redis.Client); !ok {
return nil, fmt.Errorf("allocated cache resource is not a redis client")
} else {
c.Rd = client
rdc = client
}
return c, nil
}
func (c *Conn) withTimeout() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), c.Timeout)
}

19
pkg/nex/captcha.go Normal file
View File

@@ -0,0 +1,19 @@
package nex
import (
"context"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
)
func (v *Conn) ValidateCaptcha(token, ip string) bool {
client := proto.NewCaptchaServiceClient(v.nexusConn)
resp, err := client.CheckCaptcha(context.Background(), &proto.CheckCaptchaRequest{
Token: token,
RemoteIp: ip,
})
if err != nil {
return false
}
return resp.GetIsValid()
}

View File

@@ -1,150 +0,0 @@
package nex
import (
"context"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"google.golang.org/grpc"
health "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/reflection"
"net"
"net/http"
"strconv"
"strings"
"time"
)
type CommandHandler func(ctx *CommandCtx) error
func GetCommandKey(id, method string) string {
return id + ":" + method
}
func (v *Conn) AddCommand(id, method string, tags []string, fn CommandHandler) error {
method = strings.ToLower(method)
dir := proto.NewCommandControllerClient(v.nexusConn)
ctx := context.Background()
ctx = metadata.AppendToOutgoingContext(ctx, "client_id", v.Info.Id)
var addingMethodQueue []string
if method == "all" {
addingMethodQueue = []string{"get", "post", "put", "patch", "delete"}
} else {
addingMethodQueue = append(addingMethodQueue, method)
}
for _, method := range addingMethodQueue {
ky := GetCommandKey(id, method)
_, err := dir.AddCommand(ctx, &proto.CommandInfo{
Id: id,
Method: method,
Tags: tags,
})
if err == nil {
v.commandHandlers[ky] = fn
} else {
return err
}
}
return nil
}
type localCommandRpcServer struct {
conn *Conn
proto.UnimplementedCommandControllerServer
health.UnimplementedHealthServer
}
func (v localCommandRpcServer) SendCommand(ctx context.Context, argument *proto.CommandArgument) (*proto.CommandReturn, error) {
ky := GetCommandKey(argument.GetCommand(), argument.GetMethod())
if handler, ok := v.conn.commandHandlers[ky]; !ok {
return &proto.CommandReturn{
Status: http.StatusNotFound,
Payload: []byte(argument.GetCommand() + " not found"),
}, nil
} else {
cc := &CommandCtx{
requestBody: argument.GetPayload(),
statusCode: http.StatusOK,
}
if md, ok := metadata.FromIncomingContext(ctx); ok {
for k, v := range md {
var val any = nil
if len(v) == 1 {
if len(v[0]) != 0 {
if i, err := strconv.ParseInt(v[0], 10, 64); err == nil {
val = i
} else if b, err := strconv.ParseBool(v[0]); err == nil {
val = b
} else if f, err := strconv.ParseFloat(v[0], 64); err == nil {
val = f
}
layouts := []string{
time.RFC3339,
"2006-01-02 15:04:05", // Example: 2024-10-20 14:55:05
"2006-01-02", // Example: 2024-10-20
}
for _, layout := range layouts {
if t, err := time.Parse(layout, v[0]); err == nil {
val = t
}
}
if val == nil {
val = v[0]
}
} else {
val = v[0]
}
} else if len(v) > 1 {
val = v
}
cc.values.Store(k, val)
}
}
if err := handler(cc); err != nil {
return nil, err
} else {
return &proto.CommandReturn{
Status: int32(cc.statusCode),
ContentType: cc.contentType,
Payload: cc.responseBody,
}, nil
}
}
}
func (v localCommandRpcServer) Check(ctx context.Context, request *health.HealthCheckRequest) (*health.HealthCheckResponse, error) {
return &health.HealthCheckResponse{
Status: health.HealthCheckResponse_SERVING,
}, nil
}
func (v localCommandRpcServer) Watch(request *health.HealthCheckRequest, server health.Health_WatchServer) error {
for {
if server.Send(&health.HealthCheckResponse{
Status: health.HealthCheckResponse_SERVING,
}) != nil {
break
}
time.Sleep(1000 * time.Millisecond)
}
return nil
}
func (v *Conn) RunCommands(addr string) error {
v.commandServer = grpc.NewServer()
service := &localCommandRpcServer{conn: v}
proto.RegisterCommandControllerServer(v.commandServer, service)
health.RegisterHealthServer(v.commandServer, service)
reflection.Register(v.commandServer)
listener, err := net.Listen("tcp", addr)
if err != nil {
return err
}
return v.commandServer.Serve(listener)
}

View File

@@ -1,90 +0,0 @@
package nex
import (
"fmt"
"github.com/goccy/go-json"
"net/http"
"sync"
)
type CommandCtx struct {
requestBody []byte
responseBody []byte
contentType string
statusCode int
values sync.Map
}
func CtxValueMustBe[T any](c *CommandCtx, key string) (T, error) {
if val, ok := c.values.Load(key); ok {
if v, ok := val.(T); ok {
return v, nil
}
}
var out T
if err := c.Write([]byte(fmt.Sprintf("value %s not found in type %T", key, out)), "text/plain+error", http.StatusBadRequest); err != nil {
return out, err
}
return out, fmt.Errorf("value %s not found", key)
}
func CtxValueShouldBe[T any](c *CommandCtx, key string, defaultValue T) T {
if val, ok := c.values.Load(key); ok {
if v, ok := val.(T); ok {
return v
}
}
return defaultValue
}
func (c *CommandCtx) Values() map[string]any {
duplicate := make(map[string]any)
c.values.Range(func(key, value any) bool {
duplicate[key.(string)] = value
return true
})
return duplicate
}
func (c *CommandCtx) ValueOrElse(key string, defaultValue any) any {
val, _ := c.values.Load(key)
if val == nil {
return defaultValue
}
return val
}
func (c *CommandCtx) Value(key string, newValue ...any) any {
if len(newValue) > 0 {
c.values.Store(key, newValue[0])
}
val, _ := c.values.Load(key)
return val
}
func (c *CommandCtx) Read() []byte {
return c.requestBody
}
func (c *CommandCtx) ReadJSON(out any) error {
return json.Unmarshal(c.requestBody, out)
}
func (c *CommandCtx) Write(data []byte, contentType string, statusCode ...int) error {
c.responseBody = data
c.contentType = contentType
if len(statusCode) > 0 {
c.statusCode = statusCode[0]
}
return nil
}
func (c *CommandCtx) JSON(data any, statusCode ...int) error {
raw, err := json.Marshal(data)
if err != nil {
return err
}
return c.Write(raw, "application/json", statusCode...)
}

View File

@@ -1,60 +0,0 @@
package nex_test
import (
"fmt"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"net/http"
"testing"
"time"
)
func TestHandleCommand(t *testing.T) {
conn, err := nex.NewNexusConn("127.0.0.1:7001", &proto.ServiceInfo{
Id: "echo01",
Type: "echo",
Label: "Echo",
GrpcAddr: "127.0.0.1:6001",
HttpAddr: nil,
})
if err != nil {
t.Fatal(fmt.Errorf("unable to connect nexus: %v", err))
}
if err := conn.RegisterService(); err != nil {
t.Fatal(fmt.Errorf("unable to register service: %v", err))
}
err = conn.AddCommand("say.hi", "all", nil, func(ctx *nex.CommandCtx) error {
return ctx.Write([]byte("Hello, World!"), "text/plain", http.StatusOK)
})
if err != nil {
t.Fatal(fmt.Errorf("unable to add command: %v", err))
return
}
err = conn.AddCommand("echo", "all", nil, func(ctx *nex.CommandCtx) error {
t.Log("Received command: ", string(ctx.Read()))
return ctx.Write(ctx.Read(), "text/plain", http.StatusOK)
})
err = conn.AddCommand("echo.details", "all", nil, func(ctx *nex.CommandCtx) error {
return ctx.JSON(map[string]any{
"values": ctx.Values(),
"body": ctx.Read(),
}, http.StatusOK)
})
if err != nil {
t.Fatal(fmt.Errorf("unable to add command: %v", err))
return
}
go func() {
err := conn.RunCommands("0.0.0.0:6001")
if err != nil {
t.Error(fmt.Errorf("unable to run commands: %v", err))
return
}
}()
t.Log("Waiting 60 seconds for calling command...")
time.Sleep(time.Second * 60)
}

View File

@@ -2,24 +2,20 @@ package nex
import (
"context"
"google.golang.org/grpc/metadata"
"time"
"google.golang.org/grpc/metadata"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
health "google.golang.org/grpc/health/grpc_health_v1"
_ "github.com/mbobakov/grpc-consul-resolver"
)
type Conn struct {
Addr string
Info *proto.ServiceInfo
commandServer *grpc.Server
commandHandlers map[string]CommandHandler
nexusConn *grpc.ClientConn
clientConn map[string]*grpc.ClientConn
}
@@ -37,15 +33,13 @@ func NewNexusConn(addr string, info *proto.ServiceInfo) (*Conn, error) {
Addr: addr,
Info: info,
commandHandlers: make(map[string]CommandHandler),
nexusConn: conn,
clientConn: make(map[string]*grpc.ClientConn),
}, nil
}
func (v *Conn) RegisterService() error {
dir := proto.NewServiceDirectoryClient(v.nexusConn)
dir := proto.NewDirectoryServiceClient(v.nexusConn)
ctx := context.Background()
ctx = metadata.AppendToOutgoingContext(ctx, "client_id", v.Info.Id)
_, err := dir.AddService(ctx, v.Info)
@@ -91,7 +85,7 @@ func (v *Conn) GetClientGrpcConn(t string) (*grpc.ClientConn, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
out, err := proto.NewServiceDirectoryClient(v.nexusConn).GetService(ctx, &proto.GetServiceRequest{
out, err := proto.NewDirectoryServiceClient(v.nexusConn).GetService(ctx, &proto.GetServiceRequest{
Type: &t,
})
if err != nil {

6
pkg/nex/const.go Normal file
View File

@@ -0,0 +1,6 @@
package nex
const (
ServiceTypeAuth = "id"
ServiceTypePusher = "pusher"
)

View File

@@ -10,10 +10,10 @@ import (
)
func (v *CrudConn) AllocDatabase(name string) (string, error) {
conn := v.Conn.GetNexusGrpcConn()
conn := v.n.GetNexusGrpcConn()
ctx := context.Background()
ctx = metadata.AppendToOutgoingContext(ctx, "client_id", v.Conn.Info.Id)
out, err := proto.NewDatabaseControllerClient(conn).AllocDatabase(ctx, &proto.AllocDatabaseRequest{
ctx = metadata.AppendToOutgoingContext(ctx, "client_id", v.n.Info.Id)
out, err := proto.NewDatabaseServiceClient(conn).AllocDatabase(ctx, &proto.AllocDatabaseRequest{
Name: name,
})
if err != nil || !out.GetIsSuccess() {
@@ -24,13 +24,13 @@ func (v *CrudConn) AllocDatabase(name string) (string, error) {
if err != nil {
return "", err
}
v.db = db
v.Db = db
return dsn, nil
}
func MigrateModel[T any](v *CrudConn, model T) error {
if v.db == nil {
if v.Db == nil {
return fmt.Errorf("database has not been allocated")
}
return v.db.AutoMigrate(model)
return v.Db.AutoMigrate(model)
}

View File

@@ -1,130 +0,0 @@
package cruda
import (
"errors"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"github.com/go-playground/validator/v10"
"gorm.io/gorm"
"net/http"
)
type CrudAction func(v *CrudConn) nex.CommandHandler
func AddModel[T any](v *CrudConn, model T, id, prefix string, tags []string) error {
funcList := []CrudAction{cmdList[T], cmdGet[T], cmdCreate[T], cmdUpdate[T], cmdDelete[T]}
funcCmds := []string{".list", "", "", "", ""}
funcMethods := []string{"get", "get", "put", "patch", "delete"}
for idx, fn := range funcList {
if err := v.Conn.AddCommand(prefix+id+funcCmds[idx], funcMethods[idx], tags, fn(v)); err != nil {
return err
}
}
return nil
}
var validate = validator.New(validator.WithRequiredStructEnabled())
func cmdList[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
take := int(nex.CtxValueShouldBe[int64](ctx, "query.take", 10))
skip := int(nex.CtxValueShouldBe[int64](ctx, "query.skip", 0))
var str T
var count int64
if err := c.db.Model(str).Count(&count).Error; err != nil {
return err
}
var out []T
if err := c.db.Offset(skip).Limit(take).Find(&out).Error; err != nil {
return err
}
return ctx.JSON(map[string]any{
"count": count,
"data": out,
}, http.StatusOK)
}
}
func cmdGet[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
id, err := nex.CtxValueMustBe[int64](ctx, "query.id")
if err != nil {
return err
}
var out T
if err := c.db.First(&out, "id = ?", id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return ctx.Write([]byte(err.Error()), "text/plain", http.StatusNotFound)
}
return err
}
return ctx.JSON(out, http.StatusOK)
}
}
func cmdCreate[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
var payload T
if err := ctx.ReadJSON(&payload); err != nil {
return err
} else if err := validate.Struct(payload); err != nil {
return ctx.Write([]byte(err.Error()), "text/plain+error", http.StatusBadRequest)
}
if err := c.db.Create(&payload).Error; err != nil {
return err
}
return ctx.JSON(payload, http.StatusOK)
}
}
func cmdUpdate[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
id, err := nex.CtxValueMustBe[int64](ctx, "query.id")
if err != nil {
return err
}
var payload T
if err := ctx.ReadJSON(&payload); err != nil {
return err
} else if err := validate.Struct(payload); err != nil {
return ctx.Write([]byte(err.Error()), "text/plain+error", http.StatusBadRequest)
}
var out T
if err := c.db.Model(out).Where("id = ?", id).Updates(&payload).Error; err != nil {
return err
}
if err := c.db.First(&out, "id = ?", id).Error; err != nil {
return err
}
return ctx.JSON(out, http.StatusOK)
}
}
func cmdDelete[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
id, err := nex.CtxValueMustBe[int64](ctx, "query.id")
if err != nil {
return err
}
var out T
if err := c.db.Delete(&out, "id = ?", id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return ctx.Write([]byte(err.Error()), "text/plain", http.StatusNotFound)
}
return err
}
return ctx.Write(nil, "text/plain", http.StatusOK)
}
}

View File

@@ -1,58 +0,0 @@
package cruda_test
import (
"fmt"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"git.solsynth.dev/hypernet/nexus/pkg/nex/cruda"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"testing"
"time"
)
type Test struct {
cruda.BaseModel
Content string `json:"content" validate:"required"`
}
func TestCrudaCommand(t *testing.T) {
conn, err := nex.NewNexusConn("127.0.0.1:7001", &proto.ServiceInfo{
Id: "cruda01",
Type: "cruda",
Label: "CRUD Accelerator",
GrpcAddr: "127.0.0.1:6001",
HttpAddr: nil,
})
if err != nil {
t.Fatal(fmt.Errorf("unable to connect nexus: %v", err))
}
if err := conn.RegisterService(); err != nil {
t.Fatal(fmt.Errorf("unable to register service: %v", err))
}
cc := cruda.NewCrudaConn(conn)
dsn, err := cc.AllocDatabase("test")
if err != nil {
t.Fatal(fmt.Errorf("unable to allocate database: %v", err))
}
t.Log(fmt.Sprintf("Allocated database: %s", dsn))
if err := cruda.MigrateModel(cc, Test{}); err != nil {
t.Fatal(fmt.Errorf("unable to migrate database: %v", err))
}
if err := cruda.AddModel(cc, Test{}, "tm", "test.", nil); err != nil {
t.Fatal(fmt.Errorf("unable to add commands: %v", err))
}
go func() {
err := conn.RunCommands("0.0.0.0:6001")
if err != nil {
t.Error(fmt.Errorf("unable to run commands: %v", err))
return
}
}()
t.Log("Waiting 180 seconds for calling command...")
time.Sleep(time.Second * 180)
}

View File

@@ -6,13 +6,13 @@ import (
)
type CrudConn struct {
Conn *nex.Conn
n *nex.Conn
db *gorm.DB
Db *gorm.DB
}
func NewCrudaConn(conn *nex.Conn) *CrudConn {
return &CrudConn{
Conn: conn,
n: conn,
}
}

View File

@@ -1,14 +1,16 @@
package nex
import jsoniter "github.com/json-iterator/go"
import (
"github.com/goccy/go-json"
)
func EncodeMap(data any) []byte {
raw, _ := jsoniter.Marshal(data)
raw, _ := json.Marshal(data)
return raw
}
func DecodeMap(raw []byte) map[string]any {
var out map[string]any
_ = jsoniter.Unmarshal(raw, &out)
_ = json.Unmarshal(raw, &out)
return out
}

139
pkg/nex/localize/bundle.go Normal file
View File

@@ -0,0 +1,139 @@
package localize
import (
"errors"
"fmt"
"github.com/goccy/go-json"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/rs/zerolog/log"
"golang.org/x/text/language"
htmpl "html/template"
"os"
"path/filepath"
"strings"
"text/template"
)
type Bundle struct {
Bundle *i18n.Bundle
LocalesPath string
TemplatesPath string
}
const FallbackLanguage = "en-US"
var L *Bundle
func LoadLocalization(localesPath string, templatesPath ...string) error {
L = &Bundle{
LocalesPath: localesPath,
}
if len(templatesPath) > 0 {
L.TemplatesPath = templatesPath[0]
}
L.Bundle = i18n.NewBundle(language.AmericanEnglish)
L.Bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
var count int
basePath := localesPath
if entries, err := os.ReadDir(basePath); err != nil {
return fmt.Errorf("unable to read locales directory: %v", err)
} else {
for _, entry := range entries {
if entry.IsDir() {
continue
}
if _, err := L.Bundle.LoadMessageFile(filepath.Join(basePath, entry.Name())); err != nil {
return fmt.Errorf("unable to load localization file %s: %v", entry.Name(), err)
} else {
count++
}
}
}
log.Info().Int("locales", count).Msg("Loaded localization files...")
return nil
}
func (v *Bundle) GetLocalizer(lang string) *i18n.Localizer {
return i18n.NewLocalizer(v.Bundle, lang)
}
func (v *Bundle) GetLocalizedString(name string, lang string) string {
localizer := v.GetLocalizer(lang)
msg, err := localizer.LocalizeMessage(&i18n.Message{
ID: name,
})
if err != nil {
log.Warn().Err(err).Str("lang", lang).Str("name", name).Msg("Failed to localize string...")
return name
}
return msg
}
func (v *Bundle) GetLocalizedTemplatePath(name string, lang string) string {
basePath := v.TemplatesPath
filePath := filepath.Join(basePath, lang, name)
if _, err := os.Stat(filePath); errors.Is(err, os.ErrNotExist) {
// Fallback to English
filePath = filepath.Join(basePath, FallbackLanguage, name)
return filePath
}
return filePath
}
func (v *Bundle) GetLocalizedTemplate(name string, lang string) *template.Template {
path := v.GetLocalizedTemplatePath(name, lang)
tmpl, err := template.ParseFiles(path)
if err != nil {
log.Warn().Err(err).Str("lang", lang).Str("name", name).Msg("Failed to load localized template...")
return nil
}
return tmpl
}
func (v *Bundle) GetLocalizedTemplateHTML(name string, lang string) *htmpl.Template {
path := v.GetLocalizedTemplatePath(name, lang)
tmpl, err := htmpl.ParseFiles(path)
if err != nil {
log.Warn().Err(err).Str("lang", lang).Str("name", name).Msg("Failed to load localized template...")
return nil
}
return tmpl
}
func (v *Bundle) RenderLocalizedTemplateHTML(name string, lang string, data any) string {
tmpl := v.GetLocalizedTemplate(name, lang)
if tmpl == nil {
return ""
}
buf := new(strings.Builder)
err := tmpl.Execute(buf, data)
if err != nil {
log.Warn().Err(err).Str("lang", lang).Str("name", name).Msg("Failed to render localized template...")
return ""
}
return buf.String()
}
func (v *Bundle) RenderLocalizedTemplate(name string, lang string, data any) string {
tmpl := v.GetLocalizedTemplate(name, lang)
if tmpl == nil {
return ""
}
buf := new(strings.Builder)
err := tmpl.Execute(buf, data)
if err != nil {
log.Warn().Err(err).Str("lang", lang).Str("name", name).Msg("Failed to render localized template...")
return ""
}
return buf.String()
}

32
pkg/nex/rx/mq_conn.go Normal file
View File

@@ -0,0 +1,32 @@
package rx
import (
"fmt"
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"github.com/nats-io/nats.go"
)
type MqConn struct {
n *nex.Conn
Nt *nats.Conn
}
func NewMqConn(conn *nex.Conn) (*MqConn, error) {
c := &MqConn{
n: conn,
}
mqAddr := conn.AllocResource(nex.AllocatableResourceMq)
if mqAddr == nil {
return nil, fmt.Errorf("unable to allocate resource: message queue")
} else if addr, ok := mqAddr.(string); !ok {
return nil, fmt.Errorf("alloced mq resource address is not a string")
} else if nc, err := nats.Connect(addr); err != nil {
return nil, fmt.Errorf("unable to connect to nats server: %v", err)
} else {
c.Nt = nc
}
return c, nil
}

7
pkg/nex/rx/mq_io.go Normal file
View File

@@ -0,0 +1,7 @@
package rx
import "git.solsynth.dev/hypernet/nexus/pkg/nex"
func (v *MqConn) Publish(topic string, data any) error {
return v.Nt.Publish(topic, nex.EncodeMap(data))
}

59
pkg/nex/sec/adaptor.go Normal file
View File

@@ -0,0 +1,59 @@
package sec
import (
"fmt"
"github.com/gofiber/fiber/v2"
"strings"
)
// ContextMiddleware provide a middleware to receive the userinfo from the nexus.
// It only works on the client-side of nexus.
// It will NOT validate the auth status if you need to validate the status of current authorization, refer to ValidatorMiddleware.
// To get the userinfo, call `c.Locals('nex_user').(sec.UserInfo)`
// Make sure you got the right public key, otherwise the auth will fail.
func ContextMiddleware(tkReader *InternalTokenReader) fiber.Handler {
return func(c *fiber.Ctx) error {
token := c.Get(fiber.HeaderAuthorization)
token = strings.TrimSpace(strings.Replace(token, "Bearer ", "", 1))
if len(token) == 0 {
return c.Next()
}
data, err := tkReader.ReadUserInfoJwt(token)
if err != nil {
return fiber.NewError(fiber.StatusUnauthorized, err.Error())
}
c.Locals("nex_user", data)
return c.Next()
}
}
// ValidatorMiddleware will ensure the request is authenticated
// Make sure call this middleware after ContextMiddleware
func ValidatorMiddleware(c *fiber.Ctx) error {
if c.Locals("nex_user") == nil {
return fiber.NewError(fiber.StatusUnauthorized, "unauthorized")
}
return c.Next()
}
func EnsureAuthenticated(c *fiber.Ctx) error {
if _, ok := c.Locals("nex_user").(*UserInfo); !ok {
return fiber.NewError(fiber.StatusUnauthorized)
}
return nil
}
func EnsureGrantedPerm(c *fiber.Ctx, key string, val any) error {
if err := EnsureAuthenticated(c); err != nil {
return err
}
info := c.Locals("nex_user").(*UserInfo)
if !info.HasPermNode(key, val) {
return fiber.NewError(fiber.StatusForbidden, fmt.Sprintf("missing permission: %s", key))
}
return nil
}

12
pkg/nex/sec/const.go Normal file
View File

@@ -0,0 +1,12 @@
package sec
const (
CookieAccessToken = "nex_atk"
CookieRefreshToken = "nex_rtk"
)
const (
TokenTypeAccess = "access_token"
RefreshTokenType = "refresh_token"
IdTokenType = "id_token"
)

36
pkg/nex/sec/info.go Normal file
View File

@@ -0,0 +1,36 @@
package sec
import (
"git.solsynth.dev/hypernet/nexus/pkg/nex"
"git.solsynth.dev/hypernet/nexus/pkg/proto"
"github.com/goccy/go-json"
"gorm.io/datatypes"
)
// UserInfo is the basic of userinfo, you can add anything above it.
// Full data from id service was stored in the metadata field.
type UserInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
PermNodes datatypes.JSONMap `json:"perm_nodes" gorm:"-"`
Metadata datatypes.JSONMap `json:"metadata"`
}
func NewUserInfoFromProto(in *proto.UserInfo) UserInfo {
return UserInfo{
ID: uint(in.Id),
Name: in.Name,
PermNodes: nex.DecodeMap(in.PermNodes),
Metadata: nex.DecodeMap(in.Metadata),
}
}
func NewUserInfoFromBytes(in []byte) (UserInfo, error) {
var info UserInfo
err := json.Unmarshal(in, &info)
return info, err
}
func (v UserInfo) Encode() []byte {
return nex.EncodeMap(v)
}

View File

@@ -0,0 +1,108 @@
package sec
import (
"crypto/ed25519"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"github.com/golang-jwt/jwt/v5"
"os"
"time"
)
type InternalTokenWriter struct {
pk ed25519.PrivateKey
}
func NewInternalTokenWriter(fp string) (*InternalTokenWriter, error) {
rawKey, err := os.ReadFile(fp)
if err != nil {
return nil, err
}
block, _ := pem.Decode(rawKey)
if block == nil || block.Type != "PRIVATE KEY" {
return nil, fmt.Errorf("failed to decode PEM block containing private key")
}
anyPk, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
pk, ok := anyPk.(ed25519.PrivateKey)
if !ok {
return nil, fmt.Errorf("not an Ed25519 private key")
}
return &InternalTokenWriter{
pk: pk,
}, nil
}
func (v *InternalTokenWriter) WriteUserInfoJwt(in UserInfo, audiences ...string) (string, error) {
rawData := base64.StdEncoding.EncodeToString(in.Encode())
claims := jwt.RegisteredClaims{
NotBefore: jwt.NewNumericDate(time.Now()),
IssuedAt: jwt.NewNumericDate(time.Now()),
ExpiresAt: jwt.NewNumericDate(time.Now().Add(5 * time.Minute)),
Audience: audiences,
Issuer: "nexus",
Subject: rawData,
}
token := jwt.NewWithClaims(jwt.SigningMethodEdDSA, claims)
return token.SignedString(v.pk)
}
type InternalTokenReader struct {
pk ed25519.PublicKey
}
func NewInternalTokenReader(fp string) (*InternalTokenReader, error) {
rawKey, err := os.ReadFile(fp)
if err != nil {
return nil, err
}
block, _ := pem.Decode(rawKey)
if block == nil || block.Type != "PUBLIC KEY" {
return nil, fmt.Errorf("failed to decode PEM block containing private key")
}
anyPk, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
pk, ok := anyPk.(ed25519.PublicKey)
if !ok {
return nil, fmt.Errorf("not an Ed25519 public key")
}
return &InternalTokenReader{
pk: pk,
}, nil
}
func (v *InternalTokenReader) ReadUserInfoJwt(in string) (*UserInfo, error) {
token, err := jwt.ParseWithClaims(in, &jwt.RegisteredClaims{}, func(token *jwt.Token) (interface{}, error) {
return v.pk, nil
})
if err != nil {
return nil, err
}
if !token.Valid {
return nil, fmt.Errorf("invalid token")
}
claims, ok := token.Claims.(*jwt.RegisteredClaims)
if !ok {
return nil, fmt.Errorf("invalid claims")
}
rawData, err := base64.StdEncoding.DecodeString(claims.Subject)
if err != nil {
return nil, err
}
info, err := NewUserInfoFromBytes(rawData)
return &info, err
}

27
pkg/nex/sec/jwt_claims.go Normal file
View File

@@ -0,0 +1,27 @@
package sec
import (
"github.com/golang-jwt/jwt/v5"
"time"
)
type JwtClaims struct {
jwt.RegisteredClaims
// Nexus Standard
Session string `json:"sed"`
CacheTTL time.Duration `json:"ttl,omitempty"`
// OIDC Standard
Name string `json:"name,omitempty"`
Nick string `json:"preferred_username,omitempty"`
Email string `json:"email,omitempty"`
// OAuth2 Standard
AuthorizedParties string `json:"azp,omitempty"`
Nonce string `json:"nonce,omitempty"`
// The usage of this token
// Can be access_token, refresh_token or id_token
Type string `json:"typ"`
}

80
pkg/nex/sec/jwt_reader.go Normal file
View File

@@ -0,0 +1,80 @@
package sec
import (
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"github.com/golang-jwt/jwt/v5"
"math/big"
"os"
)
type JwtReader struct {
key *rsa.PublicKey
}
func NewJwtReader(fp string) (*JwtReader, error) {
rawKey, err := os.ReadFile(fp)
if err != nil {
return nil, err
}
block, _ := pem.Decode(rawKey)
if block == nil || block.Type != "PUBLIC KEY" {
return nil, fmt.Errorf("failed to decode PEM block containing private key")
}
anyPk, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
pk, ok := anyPk.(*rsa.PublicKey)
if !ok {
return nil, fmt.Errorf("not an RSA public key")
}
return &JwtReader{
key: pk,
}, nil
}
// ReadJwt is the helper method to help me validate and parse jwt.
// To use it, pass the initialized jwt reader which contains a public key.
// And pass the token string and a pointer struct (you must initialize it, which it cannot be nil) of your claims
func ReadJwt[T jwt.Claims](v *JwtReader, in string, out T) (T, error) {
token, err := jwt.ParseWithClaims(in, out, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return v.key, nil
})
if err != nil {
return out, err
} else if !token.Valid {
return out, fmt.Errorf("token is not valid")
}
if claims, ok := token.Claims.(T); ok {
return claims, nil
} else {
return out, err
}
}
func (v *JwtReader) BuildJwk(kid string) map[string]any {
encodeBigInt := func(i *big.Int) string {
return base64.RawURLEncoding.EncodeToString(i.Bytes())
}
return map[string]any{
"kid": kid,
"kty": "RSA",
"use": "sig",
"alg": "RS256",
"n": encodeBigInt(v.key.N),
"e": encodeBigInt(big.NewInt(int64(v.key.E))),
}
}

45
pkg/nex/sec/jwt_writer.go Normal file
View File

@@ -0,0 +1,45 @@
package sec
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"github.com/golang-jwt/jwt/v5"
"os"
)
type JwtWriter struct {
key *rsa.PrivateKey
}
func NewJwtWriter(fp string) (*JwtWriter, error) {
rawKey, err := os.ReadFile(fp)
if err != nil {
return nil, err
}
block, _ := pem.Decode(rawKey)
if block == nil || block.Type != "PRIVATE KEY" {
return nil, fmt.Errorf("failed to decode PEM block containing private key")
}
anyPk, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
pk, ok := anyPk.(*rsa.PrivateKey)
if !ok {
return nil, fmt.Errorf("not an RSA private key")
}
return &JwtWriter{
key: pk,
}, nil
}
func WriteJwt[T jwt.Claims](v *JwtWriter, in T) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodRS256, in)
return token.SignedString(v.key)
}

72
pkg/nex/sec/perms.go Normal file
View File

@@ -0,0 +1,72 @@
package sec
import (
"fmt"
"reflect"
"strconv"
)
func (v UserInfo) HasPermNode(requiredKey string, requiredValue any) bool {
if heldValue, ok := v.PermNodes[requiredKey]; ok {
return comparePermNode(heldValue, requiredValue)
}
return false
}
func (v UserInfo) HasPermNodeWithDefault(requiredKey string, requiredValue any, defaultValue any) bool {
if heldValue, ok := v.PermNodes[requiredKey]; ok {
return comparePermNode(heldValue, requiredValue)
}
return comparePermNode(defaultValue, requiredValue)
}
func comparePermNode(held any, required any) bool {
isNumeric := func(val reflect.Value) bool {
kind := val.Kind()
return kind >= reflect.Int && kind <= reflect.Uint64 || kind >= reflect.Float32 && kind <= reflect.Float64
}
toFloat64 := func(val reflect.Value) float64 {
switch val.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return float64(val.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return float64(val.Uint())
case reflect.Float32, reflect.Float64:
return val.Float()
default:
panic(fmt.Sprintf("non-numeric value of kind %s", val.Kind()))
}
}
heldValue := reflect.ValueOf(held)
requiredValue := reflect.ValueOf(required)
if isNumeric(requiredValue) && heldValue.Kind() == reflect.String {
numericValue, _ := strconv.ParseFloat(heldValue.String(), 64)
return numericValue >= toFloat64(requiredValue)
}
switch heldValue.Kind() {
case reflect.String:
if heldValue.String() == requiredValue.String() {
return true
}
case reflect.Slice, reflect.Array:
for i := 0; i < heldValue.Len(); i++ {
if reflect.DeepEqual(heldValue.Index(i).Interface(), required) {
return true
}
}
default:
if isNumeric(heldValue) && isNumeric(requiredValue) {
return toFloat64(heldValue) >= toFloat64(requiredValue)
}
if reflect.DeepEqual(held, required) {
return true
}
}
return false
}

398
pkg/proto/allocator.pb.go Normal file
View File

@@ -0,0 +1,398 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc v5.29.3
// source: allocator.proto
package proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
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 AllocMqRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AllocMqRequest) Reset() {
*x = AllocMqRequest{}
mi := &file_allocator_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AllocMqRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AllocMqRequest) ProtoMessage() {}
func (x *AllocMqRequest) ProtoReflect() protoreflect.Message {
mi := &file_allocator_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AllocMqRequest.ProtoReflect.Descriptor instead.
func (*AllocMqRequest) Descriptor() ([]byte, []int) {
return file_allocator_proto_rawDescGZIP(), []int{0}
}
type AllocMqResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AllocMqResponse) Reset() {
*x = AllocMqResponse{}
mi := &file_allocator_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AllocMqResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AllocMqResponse) ProtoMessage() {}
func (x *AllocMqResponse) ProtoReflect() protoreflect.Message {
mi := &file_allocator_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AllocMqResponse.ProtoReflect.Descriptor instead.
func (*AllocMqResponse) Descriptor() ([]byte, []int) {
return file_allocator_proto_rawDescGZIP(), []int{1}
}
func (x *AllocMqResponse) GetIsSuccess() bool {
if x != nil {
return x.IsSuccess
}
return false
}
func (x *AllocMqResponse) GetAddr() string {
if x != nil {
return x.Addr
}
return ""
}
type AllocKvRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AllocKvRequest) Reset() {
*x = AllocKvRequest{}
mi := &file_allocator_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AllocKvRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AllocKvRequest) ProtoMessage() {}
func (x *AllocKvRequest) ProtoReflect() protoreflect.Message {
mi := &file_allocator_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AllocKvRequest.ProtoReflect.Descriptor instead.
func (*AllocKvRequest) Descriptor() ([]byte, []int) {
return file_allocator_proto_rawDescGZIP(), []int{2}
}
type AllocKvResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
Endpoints []string `protobuf:"bytes,2,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AllocKvResponse) Reset() {
*x = AllocKvResponse{}
mi := &file_allocator_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AllocKvResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AllocKvResponse) ProtoMessage() {}
func (x *AllocKvResponse) ProtoReflect() protoreflect.Message {
mi := &file_allocator_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AllocKvResponse.ProtoReflect.Descriptor instead.
func (*AllocKvResponse) Descriptor() ([]byte, []int) {
return file_allocator_proto_rawDescGZIP(), []int{3}
}
func (x *AllocKvResponse) GetIsSuccess() bool {
if x != nil {
return x.IsSuccess
}
return false
}
func (x *AllocKvResponse) GetEndpoints() []string {
if x != nil {
return x.Endpoints
}
return nil
}
type AllocCacheRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Db int32 `protobuf:"varint,1,opt,name=db,proto3" json:"db,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AllocCacheRequest) Reset() {
*x = AllocCacheRequest{}
mi := &file_allocator_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AllocCacheRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AllocCacheRequest) ProtoMessage() {}
func (x *AllocCacheRequest) ProtoReflect() protoreflect.Message {
mi := &file_allocator_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AllocCacheRequest.ProtoReflect.Descriptor instead.
func (*AllocCacheRequest) Descriptor() ([]byte, []int) {
return file_allocator_proto_rawDescGZIP(), []int{4}
}
func (x *AllocCacheRequest) GetDb() int32 {
if x != nil {
return x.Db
}
return 0
}
type AllocCacheResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
Db int32 `protobuf:"varint,4,opt,name=db,proto3" json:"db,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AllocCacheResponse) Reset() {
*x = AllocCacheResponse{}
mi := &file_allocator_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AllocCacheResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AllocCacheResponse) ProtoMessage() {}
func (x *AllocCacheResponse) ProtoReflect() protoreflect.Message {
mi := &file_allocator_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AllocCacheResponse.ProtoReflect.Descriptor instead.
func (*AllocCacheResponse) Descriptor() ([]byte, []int) {
return file_allocator_proto_rawDescGZIP(), []int{5}
}
func (x *AllocCacheResponse) GetIsSuccess() bool {
if x != nil {
return x.IsSuccess
}
return false
}
func (x *AllocCacheResponse) GetAddr() string {
if x != nil {
return x.Addr
}
return ""
}
func (x *AllocCacheResponse) GetPassword() string {
if x != nil {
return x.Password
}
return ""
}
func (x *AllocCacheResponse) GetDb() int32 {
if x != nil {
return x.Db
}
return 0
}
var File_allocator_proto protoreflect.FileDescriptor
const file_allocator_proto_rawDesc = "" +
"\n" +
"\x0fallocator.proto\x12\x05proto\"\x10\n" +
"\x0eAllocMqRequest\"D\n" +
"\x0fAllocMqResponse\x12\x1d\n" +
"\n" +
"is_success\x18\x01 \x01(\bR\tisSuccess\x12\x12\n" +
"\x04addr\x18\x02 \x01(\tR\x04addr\"\x10\n" +
"\x0eAllocKvRequest\"N\n" +
"\x0fAllocKvResponse\x12\x1d\n" +
"\n" +
"is_success\x18\x01 \x01(\bR\tisSuccess\x12\x1c\n" +
"\tendpoints\x18\x02 \x03(\tR\tendpoints\"#\n" +
"\x11AllocCacheRequest\x12\x0e\n" +
"\x02db\x18\x01 \x01(\x05R\x02db\"s\n" +
"\x12AllocCacheResponse\x12\x1d\n" +
"\n" +
"is_success\x18\x01 \x01(\bR\tisSuccess\x12\x12\n" +
"\x04addr\x18\x02 \x01(\tR\x04addr\x12\x1a\n" +
"\bpassword\x18\x03 \x01(\tR\bpassword\x12\x0e\n" +
"\x02db\x18\x04 \x01(\x05R\x02db2\xd9\x01\n" +
"\x10AllocatorService\x12D\n" +
"\x11AllocMessageQueue\x12\x15.proto.AllocMqRequest\x1a\x16.proto.AllocMqResponse\"\x00\x12:\n" +
"\aAllocKv\x12\x15.proto.AllocKvRequest\x1a\x16.proto.AllocKvResponse\"\x00\x12C\n" +
"\n" +
"AllocCache\x12\x18.proto.AllocCacheRequest\x1a\x19.proto.AllocCacheResponse\"\x00B\tZ\a.;protob\x06proto3"
var (
file_allocator_proto_rawDescOnce sync.Once
file_allocator_proto_rawDescData []byte
)
func file_allocator_proto_rawDescGZIP() []byte {
file_allocator_proto_rawDescOnce.Do(func() {
file_allocator_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_allocator_proto_rawDesc), len(file_allocator_proto_rawDesc)))
})
return file_allocator_proto_rawDescData
}
var file_allocator_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_allocator_proto_goTypes = []any{
(*AllocMqRequest)(nil), // 0: proto.AllocMqRequest
(*AllocMqResponse)(nil), // 1: proto.AllocMqResponse
(*AllocKvRequest)(nil), // 2: proto.AllocKvRequest
(*AllocKvResponse)(nil), // 3: proto.AllocKvResponse
(*AllocCacheRequest)(nil), // 4: proto.AllocCacheRequest
(*AllocCacheResponse)(nil), // 5: proto.AllocCacheResponse
}
var file_allocator_proto_depIdxs = []int32{
0, // 0: proto.AllocatorService.AllocMessageQueue:input_type -> proto.AllocMqRequest
2, // 1: proto.AllocatorService.AllocKv:input_type -> proto.AllocKvRequest
4, // 2: proto.AllocatorService.AllocCache:input_type -> proto.AllocCacheRequest
1, // 3: proto.AllocatorService.AllocMessageQueue:output_type -> proto.AllocMqResponse
3, // 4: proto.AllocatorService.AllocKv:output_type -> proto.AllocKvResponse
5, // 5: proto.AllocatorService.AllocCache:output_type -> proto.AllocCacheResponse
3, // [3:6] is the sub-list for method output_type
0, // [0:3] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_allocator_proto_init() }
func file_allocator_proto_init() {
if File_allocator_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_allocator_proto_rawDesc), len(file_allocator_proto_rawDesc)),
NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_allocator_proto_goTypes,
DependencyIndexes: file_allocator_proto_depIdxs,
MessageInfos: file_allocator_proto_msgTypes,
}.Build()
File_allocator_proto = out.File
file_allocator_proto_goTypes = nil
file_allocator_proto_depIdxs = nil
}

38
pkg/proto/allocator.proto Normal file
View File

@@ -0,0 +1,38 @@
syntax = "proto3";
option go_package = ".;proto";
package proto;
service AllocatorService {
rpc AllocMessageQueue(AllocMqRequest) returns (AllocMqResponse) {}
rpc AllocKv(AllocKvRequest) returns (AllocKvResponse) {}
rpc AllocCache(AllocCacheRequest) returns (AllocCacheResponse) {}
}
message AllocMqRequest {
}
message AllocMqResponse {
bool is_success = 1;
string addr = 2;
}
message AllocKvRequest {
}
message AllocKvResponse {
bool is_success = 1;
repeated string endpoints = 2;
}
message AllocCacheRequest {
int32 db = 1;
}
message AllocCacheResponse {
bool is_success = 1;
string addr = 2;
string password = 3;
int32 db = 4;
}

View File

@@ -0,0 +1,197 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v5.29.3
// source: allocator.proto
package proto
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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
AllocatorService_AllocMessageQueue_FullMethodName = "/proto.AllocatorService/AllocMessageQueue"
AllocatorService_AllocKv_FullMethodName = "/proto.AllocatorService/AllocKv"
AllocatorService_AllocCache_FullMethodName = "/proto.AllocatorService/AllocCache"
)
// AllocatorServiceClient is the client API for AllocatorService 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 AllocatorServiceClient interface {
AllocMessageQueue(ctx context.Context, in *AllocMqRequest, opts ...grpc.CallOption) (*AllocMqResponse, error)
AllocKv(ctx context.Context, in *AllocKvRequest, opts ...grpc.CallOption) (*AllocKvResponse, error)
AllocCache(ctx context.Context, in *AllocCacheRequest, opts ...grpc.CallOption) (*AllocCacheResponse, error)
}
type allocatorServiceClient struct {
cc grpc.ClientConnInterface
}
func NewAllocatorServiceClient(cc grpc.ClientConnInterface) AllocatorServiceClient {
return &allocatorServiceClient{cc}
}
func (c *allocatorServiceClient) AllocMessageQueue(ctx context.Context, in *AllocMqRequest, opts ...grpc.CallOption) (*AllocMqResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AllocMqResponse)
err := c.cc.Invoke(ctx, AllocatorService_AllocMessageQueue_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *allocatorServiceClient) AllocKv(ctx context.Context, in *AllocKvRequest, opts ...grpc.CallOption) (*AllocKvResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AllocKvResponse)
err := c.cc.Invoke(ctx, AllocatorService_AllocKv_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *allocatorServiceClient) AllocCache(ctx context.Context, in *AllocCacheRequest, opts ...grpc.CallOption) (*AllocCacheResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AllocCacheResponse)
err := c.cc.Invoke(ctx, AllocatorService_AllocCache_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// AllocatorServiceServer is the server API for AllocatorService service.
// All implementations must embed UnimplementedAllocatorServiceServer
// for forward compatibility.
type AllocatorServiceServer interface {
AllocMessageQueue(context.Context, *AllocMqRequest) (*AllocMqResponse, error)
AllocKv(context.Context, *AllocKvRequest) (*AllocKvResponse, error)
AllocCache(context.Context, *AllocCacheRequest) (*AllocCacheResponse, error)
mustEmbedUnimplementedAllocatorServiceServer()
}
// UnimplementedAllocatorServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedAllocatorServiceServer struct{}
func (UnimplementedAllocatorServiceServer) AllocMessageQueue(context.Context, *AllocMqRequest) (*AllocMqResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AllocMessageQueue not implemented")
}
func (UnimplementedAllocatorServiceServer) AllocKv(context.Context, *AllocKvRequest) (*AllocKvResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AllocKv not implemented")
}
func (UnimplementedAllocatorServiceServer) AllocCache(context.Context, *AllocCacheRequest) (*AllocCacheResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AllocCache not implemented")
}
func (UnimplementedAllocatorServiceServer) mustEmbedUnimplementedAllocatorServiceServer() {}
func (UnimplementedAllocatorServiceServer) testEmbeddedByValue() {}
// UnsafeAllocatorServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to AllocatorServiceServer will
// result in compilation errors.
type UnsafeAllocatorServiceServer interface {
mustEmbedUnimplementedAllocatorServiceServer()
}
func RegisterAllocatorServiceServer(s grpc.ServiceRegistrar, srv AllocatorServiceServer) {
// If the following call pancis, it indicates UnimplementedAllocatorServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&AllocatorService_ServiceDesc, srv)
}
func _AllocatorService_AllocMessageQueue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AllocMqRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AllocatorServiceServer).AllocMessageQueue(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AllocatorService_AllocMessageQueue_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AllocatorServiceServer).AllocMessageQueue(ctx, req.(*AllocMqRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AllocatorService_AllocKv_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AllocKvRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AllocatorServiceServer).AllocKv(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AllocatorService_AllocKv_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AllocatorServiceServer).AllocKv(ctx, req.(*AllocKvRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AllocatorService_AllocCache_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AllocCacheRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AllocatorServiceServer).AllocCache(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AllocatorService_AllocCache_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AllocatorServiceServer).AllocCache(ctx, req.(*AllocCacheRequest))
}
return interceptor(ctx, in, info, handler)
}
// AllocatorService_ServiceDesc is the grpc.ServiceDesc for AllocatorService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var AllocatorService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.AllocatorService",
HandlerType: (*AllocatorServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "AllocMessageQueue",
Handler: _AllocatorService_AllocMessageQueue_Handler,
},
{
MethodName: "AllocKv",
Handler: _AllocatorService_AllocKv_Handler,
},
{
MethodName: "AllocCache",
Handler: _AllocatorService_AllocCache_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "allocator.proto",
}

View File

@@ -1,755 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.1
// protoc v5.28.2
// source: auth.proto
package proto
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 UserInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Metadata []byte `protobuf:"bytes,3,opt,name=metadata,proto3,oneof" json:"metadata,omitempty"`
}
func (x *UserInfo) Reset() {
*x = UserInfo{}
mi := &file_auth_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UserInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UserInfo) ProtoMessage() {}
func (x *UserInfo) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UserInfo.ProtoReflect.Descriptor instead.
func (*UserInfo) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{0}
}
func (x *UserInfo) GetId() uint64 {
if x != nil {
return x.Id
}
return 0
}
func (x *UserInfo) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *UserInfo) GetMetadata() []byte {
if x != nil {
return x.Metadata
}
return nil
}
type AuthInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Info *UserInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"`
PermNodes []byte `protobuf:"bytes,2,opt,name=perm_nodes,json=permNodes,proto3" json:"perm_nodes,omitempty"`
SessionId uint64 `protobuf:"varint,3,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
NewAccessToken *string `protobuf:"bytes,4,opt,name=new_access_token,json=newAccessToken,proto3,oneof" json:"new_access_token,omitempty"`
NewRefreshToken *string `protobuf:"bytes,5,opt,name=new_refresh_token,json=newRefreshToken,proto3,oneof" json:"new_refresh_token,omitempty"`
}
func (x *AuthInfo) Reset() {
*x = AuthInfo{}
mi := &file_auth_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AuthInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthInfo) ProtoMessage() {}
func (x *AuthInfo) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthInfo.ProtoReflect.Descriptor instead.
func (*AuthInfo) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{1}
}
func (x *AuthInfo) GetInfo() *UserInfo {
if x != nil {
return x.Info
}
return nil
}
func (x *AuthInfo) GetPermNodes() []byte {
if x != nil {
return x.PermNodes
}
return nil
}
func (x *AuthInfo) GetSessionId() uint64 {
if x != nil {
return x.SessionId
}
return 0
}
func (x *AuthInfo) GetNewAccessToken() string {
if x != nil && x.NewAccessToken != nil {
return *x.NewAccessToken
}
return ""
}
func (x *AuthInfo) GetNewRefreshToken() string {
if x != nil && x.NewRefreshToken != nil {
return *x.NewRefreshToken
}
return ""
}
type AuthRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
RefreshToken *string `protobuf:"bytes,2,opt,name=refresh_token,json=refreshToken,proto3,oneof" json:"refresh_token,omitempty"`
}
func (x *AuthRequest) Reset() {
*x = AuthRequest{}
mi := &file_auth_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AuthRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthRequest) ProtoMessage() {}
func (x *AuthRequest) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthRequest.ProtoReflect.Descriptor instead.
func (*AuthRequest) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{2}
}
func (x *AuthRequest) GetAccessToken() string {
if x != nil {
return x.AccessToken
}
return ""
}
func (x *AuthRequest) GetRefreshToken() string {
if x != nil && x.RefreshToken != nil {
return *x.RefreshToken
}
return ""
}
type AuthReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
Info *AuthInfo `protobuf:"bytes,2,opt,name=info,proto3,oneof" json:"info,omitempty"`
}
func (x *AuthReply) Reset() {
*x = AuthReply{}
mi := &file_auth_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AuthReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthReply) ProtoMessage() {}
func (x *AuthReply) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthReply.ProtoReflect.Descriptor instead.
func (*AuthReply) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{3}
}
func (x *AuthReply) GetIsValid() bool {
if x != nil {
return x.IsValid
}
return false
}
func (x *AuthReply) GetInfo() *AuthInfo {
if x != nil {
return x.Info
}
return nil
}
type CheckPermRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *CheckPermRequest) Reset() {
*x = CheckPermRequest{}
mi := &file_auth_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckPermRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckPermRequest) ProtoMessage() {}
func (x *CheckPermRequest) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckPermRequest.ProtoReflect.Descriptor instead.
func (*CheckPermRequest) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{4}
}
func (x *CheckPermRequest) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
func (x *CheckPermRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *CheckPermRequest) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
type CheckPermResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
}
func (x *CheckPermResponse) Reset() {
*x = CheckPermResponse{}
mi := &file_auth_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckPermResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckPermResponse) ProtoMessage() {}
func (x *CheckPermResponse) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckPermResponse.ProtoReflect.Descriptor instead.
func (*CheckPermResponse) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{5}
}
func (x *CheckPermResponse) GetIsValid() bool {
if x != nil {
return x.IsValid
}
return false
}
type CheckUserPermRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
UserId uint64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
OtherId uint64 `protobuf:"varint,2,opt,name=other_id,json=otherId,proto3" json:"other_id,omitempty"`
Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"`
Value []byte `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *CheckUserPermRequest) Reset() {
*x = CheckUserPermRequest{}
mi := &file_auth_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckUserPermRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckUserPermRequest) ProtoMessage() {}
func (x *CheckUserPermRequest) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckUserPermRequest.ProtoReflect.Descriptor instead.
func (*CheckUserPermRequest) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{6}
}
func (x *CheckUserPermRequest) GetUserId() uint64 {
if x != nil {
return x.UserId
}
return 0
}
func (x *CheckUserPermRequest) GetOtherId() uint64 {
if x != nil {
return x.OtherId
}
return 0
}
func (x *CheckUserPermRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *CheckUserPermRequest) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
type CheckUserPermResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
}
func (x *CheckUserPermResponse) Reset() {
*x = CheckUserPermResponse{}
mi := &file_auth_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckUserPermResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckUserPermResponse) ProtoMessage() {}
func (x *CheckUserPermResponse) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckUserPermResponse.ProtoReflect.Descriptor instead.
func (*CheckUserPermResponse) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{7}
}
func (x *CheckUserPermResponse) GetIsValid() bool {
if x != nil {
return x.IsValid
}
return false
}
type ListUserRelativeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
UserId uint64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
IsRelated bool `protobuf:"varint,3,opt,name=is_related,json=isRelated,proto3" json:"is_related,omitempty"`
}
func (x *ListUserRelativeRequest) Reset() {
*x = ListUserRelativeRequest{}
mi := &file_auth_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListUserRelativeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListUserRelativeRequest) ProtoMessage() {}
func (x *ListUserRelativeRequest) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListUserRelativeRequest.ProtoReflect.Descriptor instead.
func (*ListUserRelativeRequest) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{8}
}
func (x *ListUserRelativeRequest) GetUserId() uint64 {
if x != nil {
return x.UserId
}
return 0
}
func (x *ListUserRelativeRequest) GetStatus() int32 {
if x != nil {
return x.Status
}
return 0
}
func (x *ListUserRelativeRequest) GetIsRelated() bool {
if x != nil {
return x.IsRelated
}
return false
}
type ListUserRelativeResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Data []*UserInfo `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
}
func (x *ListUserRelativeResponse) Reset() {
*x = ListUserRelativeResponse{}
mi := &file_auth_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListUserRelativeResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListUserRelativeResponse) ProtoMessage() {}
func (x *ListUserRelativeResponse) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListUserRelativeResponse.ProtoReflect.Descriptor instead.
func (*ListUserRelativeResponse) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{9}
}
func (x *ListUserRelativeResponse) GetData() []*UserInfo {
if x != nil {
return x.Data
}
return nil
}
var File_auth_proto protoreflect.FileDescriptor
var file_auth_proto_rawDesc = []byte{
0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x5c, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x22, 0xf8, 0x01, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23,
0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69,
0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x5f, 0x6e, 0x6f, 0x64, 0x65,
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x4e, 0x6f, 0x64,
0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49,
0x64, 0x12, 0x2d, 0x0a, 0x10, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x6e,
0x65, 0x77, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01,
0x12, 0x2f, 0x0a, 0x11, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0f, 0x6e,
0x65, 0x77, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01,
0x01, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72,
0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x6c, 0x0a, 0x0b,
0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61,
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x28,
0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, 0x66,
0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x59, 0x0a, 0x09, 0x41, 0x75,
0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x76, 0x61,
0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c,
0x69, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66,
0x6f, 0x48, 0x00, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05,
0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x50, 0x0a, 0x10, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x65,
0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x2e, 0x0a, 0x11, 0x43, 0x68, 0x65, 0x63, 0x6b,
0x50, 0x65, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08,
0x69, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x22, 0x72, 0x0a, 0x14, 0x43, 0x68, 0x65, 0x63, 0x6b,
0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x74, 0x68, 0x65,
0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6f, 0x74, 0x68, 0x65,
0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x32, 0x0a, 0x15, 0x43,
0x68, 0x65, 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x22,
0x69, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x6c, 0x61, 0x74,
0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73,
0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65,
0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20,
0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69,
0x73, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
0x09, 0x69, 0x73, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x22, 0x3f, 0x0a, 0x18, 0x4c, 0x69,
0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x73, 0x65,
0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0xb5, 0x02, 0x0a, 0x04,
0x41, 0x75, 0x74, 0x68, 0x12, 0x36, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
0x63, 0x61, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74,
0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x11,
0x45, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65,
0x64, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50,
0x65, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x65, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x15, 0x45, 0x6e, 0x73, 0x75, 0x72, 0x65,
0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12,
0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x73, 0x65,
0x72, 0x50, 0x65, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65,
0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x10,
0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65,
0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65,
0x72, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65,
0x72, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_auth_proto_rawDescOnce sync.Once
file_auth_proto_rawDescData = file_auth_proto_rawDesc
)
func file_auth_proto_rawDescGZIP() []byte {
file_auth_proto_rawDescOnce.Do(func() {
file_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_auth_proto_rawDescData)
})
return file_auth_proto_rawDescData
}
var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_auth_proto_goTypes = []any{
(*UserInfo)(nil), // 0: proto.UserInfo
(*AuthInfo)(nil), // 1: proto.AuthInfo
(*AuthRequest)(nil), // 2: proto.AuthRequest
(*AuthReply)(nil), // 3: proto.AuthReply
(*CheckPermRequest)(nil), // 4: proto.CheckPermRequest
(*CheckPermResponse)(nil), // 5: proto.CheckPermResponse
(*CheckUserPermRequest)(nil), // 6: proto.CheckUserPermRequest
(*CheckUserPermResponse)(nil), // 7: proto.CheckUserPermResponse
(*ListUserRelativeRequest)(nil), // 8: proto.ListUserRelativeRequest
(*ListUserRelativeResponse)(nil), // 9: proto.ListUserRelativeResponse
}
var file_auth_proto_depIdxs = []int32{
0, // 0: proto.AuthInfo.info:type_name -> proto.UserInfo
1, // 1: proto.AuthReply.info:type_name -> proto.AuthInfo
0, // 2: proto.ListUserRelativeResponse.data:type_name -> proto.UserInfo
2, // 3: proto.Auth.Authenticate:input_type -> proto.AuthRequest
4, // 4: proto.Auth.EnsurePermGranted:input_type -> proto.CheckPermRequest
6, // 5: proto.Auth.EnsureUserPermGranted:input_type -> proto.CheckUserPermRequest
8, // 6: proto.Auth.ListUserRelative:input_type -> proto.ListUserRelativeRequest
3, // 7: proto.Auth.Authenticate:output_type -> proto.AuthReply
5, // 8: proto.Auth.EnsurePermGranted:output_type -> proto.CheckPermResponse
7, // 9: proto.Auth.EnsureUserPermGranted:output_type -> proto.CheckUserPermResponse
9, // 10: proto.Auth.ListUserRelative:output_type -> proto.ListUserRelativeResponse
7, // [7:11] is the sub-list for method output_type
3, // [3:7] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_auth_proto_init() }
func file_auth_proto_init() {
if File_auth_proto != nil {
return
}
file_auth_proto_msgTypes[0].OneofWrappers = []any{}
file_auth_proto_msgTypes[1].OneofWrappers = []any{}
file_auth_proto_msgTypes[2].OneofWrappers = []any{}
file_auth_proto_msgTypes[3].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_auth_proto_rawDesc,
NumEnums: 0,
NumMessages: 10,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_auth_proto_goTypes,
DependencyIndexes: file_auth_proto_depIdxs,
MessageInfos: file_auth_proto_msgTypes,
}.Build()
File_auth_proto = out.File
file_auth_proto_rawDesc = nil
file_auth_proto_goTypes = nil
file_auth_proto_depIdxs = nil
}

View File

@@ -1,235 +0,0 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v5.28.2
// source: auth.proto
package proto
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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
Auth_Authenticate_FullMethodName = "/proto.Auth/Authenticate"
Auth_EnsurePermGranted_FullMethodName = "/proto.Auth/EnsurePermGranted"
Auth_EnsureUserPermGranted_FullMethodName = "/proto.Auth/EnsureUserPermGranted"
Auth_ListUserRelative_FullMethodName = "/proto.Auth/ListUserRelative"
)
// AuthClient is the client API for Auth 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 AuthClient interface {
Authenticate(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*AuthReply, error)
EnsurePermGranted(ctx context.Context, in *CheckPermRequest, opts ...grpc.CallOption) (*CheckPermResponse, error)
EnsureUserPermGranted(ctx context.Context, in *CheckUserPermRequest, opts ...grpc.CallOption) (*CheckUserPermResponse, error)
ListUserRelative(ctx context.Context, in *ListUserRelativeRequest, opts ...grpc.CallOption) (*ListUserRelativeResponse, error)
}
type authClient struct {
cc grpc.ClientConnInterface
}
func NewAuthClient(cc grpc.ClientConnInterface) AuthClient {
return &authClient{cc}
}
func (c *authClient) Authenticate(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*AuthReply, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AuthReply)
err := c.cc.Invoke(ctx, Auth_Authenticate_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authClient) EnsurePermGranted(ctx context.Context, in *CheckPermRequest, opts ...grpc.CallOption) (*CheckPermResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CheckPermResponse)
err := c.cc.Invoke(ctx, Auth_EnsurePermGranted_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authClient) EnsureUserPermGranted(ctx context.Context, in *CheckUserPermRequest, opts ...grpc.CallOption) (*CheckUserPermResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CheckUserPermResponse)
err := c.cc.Invoke(ctx, Auth_EnsureUserPermGranted_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authClient) ListUserRelative(ctx context.Context, in *ListUserRelativeRequest, opts ...grpc.CallOption) (*ListUserRelativeResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListUserRelativeResponse)
err := c.cc.Invoke(ctx, Auth_ListUserRelative_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// AuthServer is the server API for Auth service.
// All implementations must embed UnimplementedAuthServer
// for forward compatibility.
type AuthServer interface {
Authenticate(context.Context, *AuthRequest) (*AuthReply, error)
EnsurePermGranted(context.Context, *CheckPermRequest) (*CheckPermResponse, error)
EnsureUserPermGranted(context.Context, *CheckUserPermRequest) (*CheckUserPermResponse, error)
ListUserRelative(context.Context, *ListUserRelativeRequest) (*ListUserRelativeResponse, error)
mustEmbedUnimplementedAuthServer()
}
// UnimplementedAuthServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedAuthServer struct{}
func (UnimplementedAuthServer) Authenticate(context.Context, *AuthRequest) (*AuthReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Authenticate not implemented")
}
func (UnimplementedAuthServer) EnsurePermGranted(context.Context, *CheckPermRequest) (*CheckPermResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EnsurePermGranted not implemented")
}
func (UnimplementedAuthServer) EnsureUserPermGranted(context.Context, *CheckUserPermRequest) (*CheckUserPermResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EnsureUserPermGranted not implemented")
}
func (UnimplementedAuthServer) ListUserRelative(context.Context, *ListUserRelativeRequest) (*ListUserRelativeResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListUserRelative not implemented")
}
func (UnimplementedAuthServer) mustEmbedUnimplementedAuthServer() {}
func (UnimplementedAuthServer) testEmbeddedByValue() {}
// UnsafeAuthServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to AuthServer will
// result in compilation errors.
type UnsafeAuthServer interface {
mustEmbedUnimplementedAuthServer()
}
func RegisterAuthServer(s grpc.ServiceRegistrar, srv AuthServer) {
// If the following call pancis, it indicates UnimplementedAuthServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&Auth_ServiceDesc, srv)
}
func _Auth_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AuthRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServer).Authenticate(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Auth_Authenticate_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServer).Authenticate(ctx, req.(*AuthRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Auth_EnsurePermGranted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CheckPermRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServer).EnsurePermGranted(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Auth_EnsurePermGranted_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServer).EnsurePermGranted(ctx, req.(*CheckPermRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Auth_EnsureUserPermGranted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CheckUserPermRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServer).EnsureUserPermGranted(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Auth_EnsureUserPermGranted_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServer).EnsureUserPermGranted(ctx, req.(*CheckUserPermRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Auth_ListUserRelative_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListUserRelativeRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServer).ListUserRelative(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Auth_ListUserRelative_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServer).ListUserRelative(ctx, req.(*ListUserRelativeRequest))
}
return interceptor(ctx, in, info, handler)
}
// Auth_ServiceDesc is the grpc.ServiceDesc for Auth service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Auth_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.Auth",
HandlerType: (*AuthServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Authenticate",
Handler: _Auth_Authenticate_Handler,
},
{
MethodName: "EnsurePermGranted",
Handler: _Auth_EnsurePermGranted_Handler,
},
{
MethodName: "EnsureUserPermGranted",
Handler: _Auth_EnsureUserPermGranted_Handler,
},
{
MethodName: "ListUserRelative",
Handler: _Auth_ListUserRelative_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "auth.proto",
}

View File

@@ -0,0 +1,487 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc v5.29.3
// source: authenticate.proto
package proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
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 AuthInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
Info *UserInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"`
SessionId uint64 `protobuf:"varint,3,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AuthInfo) Reset() {
*x = AuthInfo{}
mi := &file_authenticate_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AuthInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthInfo) ProtoMessage() {}
func (x *AuthInfo) ProtoReflect() protoreflect.Message {
mi := &file_authenticate_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthInfo.ProtoReflect.Descriptor instead.
func (*AuthInfo) Descriptor() ([]byte, []int) {
return file_authenticate_proto_rawDescGZIP(), []int{0}
}
func (x *AuthInfo) GetInfo() *UserInfo {
if x != nil {
return x.Info
}
return nil
}
func (x *AuthInfo) GetSessionId() uint64 {
if x != nil {
return x.SessionId
}
return 0
}
type AuthRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
SessionId uint64 `protobuf:"varint,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AuthRequest) Reset() {
*x = AuthRequest{}
mi := &file_authenticate_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AuthRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthRequest) ProtoMessage() {}
func (x *AuthRequest) ProtoReflect() protoreflect.Message {
mi := &file_authenticate_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthRequest.ProtoReflect.Descriptor instead.
func (*AuthRequest) Descriptor() ([]byte, []int) {
return file_authenticate_proto_rawDescGZIP(), []int{1}
}
func (x *AuthRequest) GetSessionId() uint64 {
if x != nil {
return x.SessionId
}
return 0
}
type AuthReply struct {
state protoimpl.MessageState `protogen:"open.v1"`
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
Info *AuthInfo `protobuf:"bytes,2,opt,name=info,proto3,oneof" json:"info,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AuthReply) Reset() {
*x = AuthReply{}
mi := &file_authenticate_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AuthReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthReply) ProtoMessage() {}
func (x *AuthReply) ProtoReflect() protoreflect.Message {
mi := &file_authenticate_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthReply.ProtoReflect.Descriptor instead.
func (*AuthReply) Descriptor() ([]byte, []int) {
return file_authenticate_proto_rawDescGZIP(), []int{2}
}
func (x *AuthReply) GetIsValid() bool {
if x != nil {
return x.IsValid
}
return false
}
func (x *AuthReply) GetInfo() *AuthInfo {
if x != nil {
return x.Info
}
return nil
}
type CheckPermRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
SessionId uint64 `protobuf:"varint,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckPermRequest) Reset() {
*x = CheckPermRequest{}
mi := &file_authenticate_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckPermRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckPermRequest) ProtoMessage() {}
func (x *CheckPermRequest) ProtoReflect() protoreflect.Message {
mi := &file_authenticate_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckPermRequest.ProtoReflect.Descriptor instead.
func (*CheckPermRequest) Descriptor() ([]byte, []int) {
return file_authenticate_proto_rawDescGZIP(), []int{3}
}
func (x *CheckPermRequest) GetSessionId() uint64 {
if x != nil {
return x.SessionId
}
return 0
}
func (x *CheckPermRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *CheckPermRequest) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
type CheckPermResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckPermResponse) Reset() {
*x = CheckPermResponse{}
mi := &file_authenticate_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckPermResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckPermResponse) ProtoMessage() {}
func (x *CheckPermResponse) ProtoReflect() protoreflect.Message {
mi := &file_authenticate_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckPermResponse.ProtoReflect.Descriptor instead.
func (*CheckPermResponse) Descriptor() ([]byte, []int) {
return file_authenticate_proto_rawDescGZIP(), []int{4}
}
func (x *CheckPermResponse) GetIsValid() bool {
if x != nil {
return x.IsValid
}
return false
}
type CheckUserPermRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId uint64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
OtherId uint64 `protobuf:"varint,2,opt,name=other_id,json=otherId,proto3" json:"other_id,omitempty"`
Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"`
Value []byte `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckUserPermRequest) Reset() {
*x = CheckUserPermRequest{}
mi := &file_authenticate_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckUserPermRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckUserPermRequest) ProtoMessage() {}
func (x *CheckUserPermRequest) ProtoReflect() protoreflect.Message {
mi := &file_authenticate_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckUserPermRequest.ProtoReflect.Descriptor instead.
func (*CheckUserPermRequest) Descriptor() ([]byte, []int) {
return file_authenticate_proto_rawDescGZIP(), []int{5}
}
func (x *CheckUserPermRequest) GetUserId() uint64 {
if x != nil {
return x.UserId
}
return 0
}
func (x *CheckUserPermRequest) GetOtherId() uint64 {
if x != nil {
return x.OtherId
}
return 0
}
func (x *CheckUserPermRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *CheckUserPermRequest) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
type CheckUserPermResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckUserPermResponse) Reset() {
*x = CheckUserPermResponse{}
mi := &file_authenticate_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckUserPermResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckUserPermResponse) ProtoMessage() {}
func (x *CheckUserPermResponse) ProtoReflect() protoreflect.Message {
mi := &file_authenticate_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckUserPermResponse.ProtoReflect.Descriptor instead.
func (*CheckUserPermResponse) Descriptor() ([]byte, []int) {
return file_authenticate_proto_rawDescGZIP(), []int{6}
}
func (x *CheckUserPermResponse) GetIsValid() bool {
if x != nil {
return x.IsValid
}
return false
}
var File_authenticate_proto protoreflect.FileDescriptor
const file_authenticate_proto_rawDesc = "" +
"\n" +
"\x12authenticate.proto\x12\x05proto\x1a\n" +
"user.proto\"N\n" +
"\bAuthInfo\x12#\n" +
"\x04info\x18\x01 \x01(\v2\x0f.proto.UserInfoR\x04info\x12\x1d\n" +
"\n" +
"session_id\x18\x03 \x01(\x04R\tsessionId\",\n" +
"\vAuthRequest\x12\x1d\n" +
"\n" +
"session_id\x18\x01 \x01(\x04R\tsessionId\"Y\n" +
"\tAuthReply\x12\x19\n" +
"\bis_valid\x18\x01 \x01(\bR\aisValid\x12(\n" +
"\x04info\x18\x02 \x01(\v2\x0f.proto.AuthInfoH\x00R\x04info\x88\x01\x01B\a\n" +
"\x05_info\"Y\n" +
"\x10CheckPermRequest\x12\x1d\n" +
"\n" +
"session_id\x18\x01 \x01(\x04R\tsessionId\x12\x10\n" +
"\x03key\x18\x02 \x01(\tR\x03key\x12\x14\n" +
"\x05value\x18\x03 \x01(\fR\x05value\".\n" +
"\x11CheckPermResponse\x12\x19\n" +
"\bis_valid\x18\x01 \x01(\bR\aisValid\"r\n" +
"\x14CheckUserPermRequest\x12\x17\n" +
"\auser_id\x18\x01 \x01(\x04R\x06userId\x12\x19\n" +
"\bother_id\x18\x02 \x01(\x04R\aotherId\x12\x10\n" +
"\x03key\x18\x03 \x01(\tR\x03key\x12\x14\n" +
"\x05value\x18\x04 \x01(\fR\x05value\"2\n" +
"\x15CheckUserPermResponse\x12\x19\n" +
"\bis_valid\x18\x01 \x01(\bR\aisValid2\xe5\x01\n" +
"\vAuthService\x126\n" +
"\fAuthenticate\x12\x12.proto.AuthRequest\x1a\x10.proto.AuthReply\"\x00\x12H\n" +
"\x11EnsurePermGranted\x12\x17.proto.CheckPermRequest\x1a\x18.proto.CheckPermResponse\"\x00\x12T\n" +
"\x15EnsureUserPermGranted\x12\x1b.proto.CheckUserPermRequest\x1a\x1c.proto.CheckUserPermResponse\"\x00B\tZ\a.;protob\x06proto3"
var (
file_authenticate_proto_rawDescOnce sync.Once
file_authenticate_proto_rawDescData []byte
)
func file_authenticate_proto_rawDescGZIP() []byte {
file_authenticate_proto_rawDescOnce.Do(func() {
file_authenticate_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_authenticate_proto_rawDesc), len(file_authenticate_proto_rawDesc)))
})
return file_authenticate_proto_rawDescData
}
var file_authenticate_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_authenticate_proto_goTypes = []any{
(*AuthInfo)(nil), // 0: proto.AuthInfo
(*AuthRequest)(nil), // 1: proto.AuthRequest
(*AuthReply)(nil), // 2: proto.AuthReply
(*CheckPermRequest)(nil), // 3: proto.CheckPermRequest
(*CheckPermResponse)(nil), // 4: proto.CheckPermResponse
(*CheckUserPermRequest)(nil), // 5: proto.CheckUserPermRequest
(*CheckUserPermResponse)(nil), // 6: proto.CheckUserPermResponse
(*UserInfo)(nil), // 7: proto.UserInfo
}
var file_authenticate_proto_depIdxs = []int32{
7, // 0: proto.AuthInfo.info:type_name -> proto.UserInfo
0, // 1: proto.AuthReply.info:type_name -> proto.AuthInfo
1, // 2: proto.AuthService.Authenticate:input_type -> proto.AuthRequest
3, // 3: proto.AuthService.EnsurePermGranted:input_type -> proto.CheckPermRequest
5, // 4: proto.AuthService.EnsureUserPermGranted:input_type -> proto.CheckUserPermRequest
2, // 5: proto.AuthService.Authenticate:output_type -> proto.AuthReply
4, // 6: proto.AuthService.EnsurePermGranted:output_type -> proto.CheckPermResponse
6, // 7: proto.AuthService.EnsureUserPermGranted:output_type -> proto.CheckUserPermResponse
5, // [5:8] is the sub-list for method output_type
2, // [2:5] 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_authenticate_proto_init() }
func file_authenticate_proto_init() {
if File_authenticate_proto != nil {
return
}
file_user_proto_init()
file_authenticate_proto_msgTypes[2].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_authenticate_proto_rawDesc), len(file_authenticate_proto_rawDesc)),
NumEnums: 0,
NumMessages: 7,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_authenticate_proto_goTypes,
DependencyIndexes: file_authenticate_proto_depIdxs,
MessageInfos: file_authenticate_proto_msgTypes,
}.Build()
File_authenticate_proto = out.File
file_authenticate_proto_goTypes = nil
file_authenticate_proto_depIdxs = nil
}

View File

@@ -1,33 +1,23 @@
syntax = "proto3";
import "user.proto";
option go_package = ".;proto";
package proto;
service Auth {
service AuthService {
rpc Authenticate(AuthRequest) returns (AuthReply) {}
rpc EnsurePermGranted(CheckPermRequest) returns (CheckPermResponse) {}
rpc EnsureUserPermGranted(CheckUserPermRequest) returns (CheckUserPermResponse) {}
rpc ListUserRelative(ListUserRelativeRequest) returns (ListUserRelativeResponse) {}
}
message UserInfo {
uint64 id = 1;
string name = 2;
optional bytes metadata = 3;
}
message AuthInfo {
UserInfo info = 1;
bytes perm_nodes = 2;
uint64 session_id = 3;
optional string new_access_token = 4;
optional string new_refresh_token = 5;
}
message AuthRequest {
string access_token = 1;
optional string refresh_token = 2;
uint64 session_id = 1;
}
message AuthReply {
@@ -36,7 +26,7 @@ message AuthReply {
}
message CheckPermRequest {
string token = 1;
uint64 session_id = 1;
string key = 2;
bytes value = 3;
}
@@ -55,13 +45,3 @@ message CheckUserPermRequest {
message CheckUserPermResponse {
bool is_valid = 1;
}
message ListUserRelativeRequest {
uint64 user_id = 1;
int32 status = 2;
bool is_related = 3;
}
message ListUserRelativeResponse {
repeated UserInfo data = 1;
}

View File

@@ -0,0 +1,197 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v5.29.3
// source: authenticate.proto
package proto
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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
AuthService_Authenticate_FullMethodName = "/proto.AuthService/Authenticate"
AuthService_EnsurePermGranted_FullMethodName = "/proto.AuthService/EnsurePermGranted"
AuthService_EnsureUserPermGranted_FullMethodName = "/proto.AuthService/EnsureUserPermGranted"
)
// AuthServiceClient is the client API for AuthService 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 AuthServiceClient interface {
Authenticate(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*AuthReply, error)
EnsurePermGranted(ctx context.Context, in *CheckPermRequest, opts ...grpc.CallOption) (*CheckPermResponse, error)
EnsureUserPermGranted(ctx context.Context, in *CheckUserPermRequest, opts ...grpc.CallOption) (*CheckUserPermResponse, error)
}
type authServiceClient struct {
cc grpc.ClientConnInterface
}
func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient {
return &authServiceClient{cc}
}
func (c *authServiceClient) Authenticate(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*AuthReply, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AuthReply)
err := c.cc.Invoke(ctx, AuthService_Authenticate_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authServiceClient) EnsurePermGranted(ctx context.Context, in *CheckPermRequest, opts ...grpc.CallOption) (*CheckPermResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CheckPermResponse)
err := c.cc.Invoke(ctx, AuthService_EnsurePermGranted_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authServiceClient) EnsureUserPermGranted(ctx context.Context, in *CheckUserPermRequest, opts ...grpc.CallOption) (*CheckUserPermResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CheckUserPermResponse)
err := c.cc.Invoke(ctx, AuthService_EnsureUserPermGranted_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// AuthServiceServer is the server API for AuthService service.
// All implementations must embed UnimplementedAuthServiceServer
// for forward compatibility.
type AuthServiceServer interface {
Authenticate(context.Context, *AuthRequest) (*AuthReply, error)
EnsurePermGranted(context.Context, *CheckPermRequest) (*CheckPermResponse, error)
EnsureUserPermGranted(context.Context, *CheckUserPermRequest) (*CheckUserPermResponse, error)
mustEmbedUnimplementedAuthServiceServer()
}
// UnimplementedAuthServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedAuthServiceServer struct{}
func (UnimplementedAuthServiceServer) Authenticate(context.Context, *AuthRequest) (*AuthReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Authenticate not implemented")
}
func (UnimplementedAuthServiceServer) EnsurePermGranted(context.Context, *CheckPermRequest) (*CheckPermResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EnsurePermGranted not implemented")
}
func (UnimplementedAuthServiceServer) EnsureUserPermGranted(context.Context, *CheckUserPermRequest) (*CheckUserPermResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EnsureUserPermGranted not implemented")
}
func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {}
func (UnimplementedAuthServiceServer) testEmbeddedByValue() {}
// UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to AuthServiceServer will
// result in compilation errors.
type UnsafeAuthServiceServer interface {
mustEmbedUnimplementedAuthServiceServer()
}
func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) {
// If the following call pancis, it indicates UnimplementedAuthServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&AuthService_ServiceDesc, srv)
}
func _AuthService_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AuthRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServiceServer).Authenticate(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AuthService_Authenticate_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServiceServer).Authenticate(ctx, req.(*AuthRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AuthService_EnsurePermGranted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CheckPermRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServiceServer).EnsurePermGranted(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AuthService_EnsurePermGranted_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServiceServer).EnsurePermGranted(ctx, req.(*CheckPermRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AuthService_EnsureUserPermGranted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CheckUserPermRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServiceServer).EnsureUserPermGranted(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: AuthService_EnsureUserPermGranted_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServiceServer).EnsureUserPermGranted(ctx, req.(*CheckUserPermRequest))
}
return interceptor(ctx, in, info, handler)
}
// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var AuthService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.AuthService",
HandlerType: (*AuthServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Authenticate",
Handler: _AuthService_Authenticate_Handler,
},
{
MethodName: "EnsurePermGranted",
Handler: _AuthService_EnsurePermGranted_Handler,
},
{
MethodName: "EnsureUserPermGranted",
Handler: _AuthService_EnsureUserPermGranted_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "authenticate.proto",
}

182
pkg/proto/captcha.pb.go Normal file
View File

@@ -0,0 +1,182 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc v5.29.3
// source: captcha.proto
package proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
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 CheckCaptchaRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
RemoteIp string `protobuf:"bytes,2,opt,name=remote_ip,json=remoteIp,proto3" json:"remote_ip,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckCaptchaRequest) Reset() {
*x = CheckCaptchaRequest{}
mi := &file_captcha_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckCaptchaRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckCaptchaRequest) ProtoMessage() {}
func (x *CheckCaptchaRequest) ProtoReflect() protoreflect.Message {
mi := &file_captcha_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckCaptchaRequest.ProtoReflect.Descriptor instead.
func (*CheckCaptchaRequest) Descriptor() ([]byte, []int) {
return file_captcha_proto_rawDescGZIP(), []int{0}
}
func (x *CheckCaptchaRequest) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
func (x *CheckCaptchaRequest) GetRemoteIp() string {
if x != nil {
return x.RemoteIp
}
return ""
}
type CheckCaptchaResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CheckCaptchaResponse) Reset() {
*x = CheckCaptchaResponse{}
mi := &file_captcha_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CheckCaptchaResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckCaptchaResponse) ProtoMessage() {}
func (x *CheckCaptchaResponse) ProtoReflect() protoreflect.Message {
mi := &file_captcha_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckCaptchaResponse.ProtoReflect.Descriptor instead.
func (*CheckCaptchaResponse) Descriptor() ([]byte, []int) {
return file_captcha_proto_rawDescGZIP(), []int{1}
}
func (x *CheckCaptchaResponse) GetIsValid() bool {
if x != nil {
return x.IsValid
}
return false
}
var File_captcha_proto protoreflect.FileDescriptor
const file_captcha_proto_rawDesc = "" +
"\n" +
"\rcaptcha.proto\x12\x05proto\"H\n" +
"\x13CheckCaptchaRequest\x12\x14\n" +
"\x05token\x18\x01 \x01(\tR\x05token\x12\x1b\n" +
"\tremote_ip\x18\x02 \x01(\tR\bremoteIp\"1\n" +
"\x14CheckCaptchaResponse\x12\x19\n" +
"\bis_valid\x18\x01 \x01(\bR\aisValid2[\n" +
"\x0eCaptchaService\x12I\n" +
"\fCheckCaptcha\x12\x1a.proto.CheckCaptchaRequest\x1a\x1b.proto.CheckCaptchaResponse\"\x00B\tZ\a.;protob\x06proto3"
var (
file_captcha_proto_rawDescOnce sync.Once
file_captcha_proto_rawDescData []byte
)
func file_captcha_proto_rawDescGZIP() []byte {
file_captcha_proto_rawDescOnce.Do(func() {
file_captcha_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_captcha_proto_rawDesc), len(file_captcha_proto_rawDesc)))
})
return file_captcha_proto_rawDescData
}
var file_captcha_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_captcha_proto_goTypes = []any{
(*CheckCaptchaRequest)(nil), // 0: proto.CheckCaptchaRequest
(*CheckCaptchaResponse)(nil), // 1: proto.CheckCaptchaResponse
}
var file_captcha_proto_depIdxs = []int32{
0, // 0: proto.CaptchaService.CheckCaptcha:input_type -> proto.CheckCaptchaRequest
1, // 1: proto.CaptchaService.CheckCaptcha:output_type -> proto.CheckCaptchaResponse
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_captcha_proto_init() }
func file_captcha_proto_init() {
if File_captcha_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_captcha_proto_rawDesc), len(file_captcha_proto_rawDesc)),
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_captcha_proto_goTypes,
DependencyIndexes: file_captcha_proto_depIdxs,
MessageInfos: file_captcha_proto_msgTypes,
}.Build()
File_captcha_proto = out.File
file_captcha_proto_goTypes = nil
file_captcha_proto_depIdxs = nil
}

18
pkg/proto/captcha.proto Normal file
View File

@@ -0,0 +1,18 @@
syntax = "proto3";
option go_package = ".;proto";
package proto;
service CaptchaService {
rpc CheckCaptcha(CheckCaptchaRequest) returns (CheckCaptchaResponse) {}
}
message CheckCaptchaRequest {
string token = 1;
string remote_ip = 2;
}
message CheckCaptchaResponse {
bool is_valid = 1;
}

View File

@@ -0,0 +1,121 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v5.29.3
// source: captcha.proto
package proto
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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
CaptchaService_CheckCaptcha_FullMethodName = "/proto.CaptchaService/CheckCaptcha"
)
// CaptchaServiceClient is the client API for CaptchaService 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 CaptchaServiceClient interface {
CheckCaptcha(ctx context.Context, in *CheckCaptchaRequest, opts ...grpc.CallOption) (*CheckCaptchaResponse, error)
}
type captchaServiceClient struct {
cc grpc.ClientConnInterface
}
func NewCaptchaServiceClient(cc grpc.ClientConnInterface) CaptchaServiceClient {
return &captchaServiceClient{cc}
}
func (c *captchaServiceClient) CheckCaptcha(ctx context.Context, in *CheckCaptchaRequest, opts ...grpc.CallOption) (*CheckCaptchaResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CheckCaptchaResponse)
err := c.cc.Invoke(ctx, CaptchaService_CheckCaptcha_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// CaptchaServiceServer is the server API for CaptchaService service.
// All implementations must embed UnimplementedCaptchaServiceServer
// for forward compatibility.
type CaptchaServiceServer interface {
CheckCaptcha(context.Context, *CheckCaptchaRequest) (*CheckCaptchaResponse, error)
mustEmbedUnimplementedCaptchaServiceServer()
}
// UnimplementedCaptchaServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedCaptchaServiceServer struct{}
func (UnimplementedCaptchaServiceServer) CheckCaptcha(context.Context, *CheckCaptchaRequest) (*CheckCaptchaResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CheckCaptcha not implemented")
}
func (UnimplementedCaptchaServiceServer) mustEmbedUnimplementedCaptchaServiceServer() {}
func (UnimplementedCaptchaServiceServer) testEmbeddedByValue() {}
// UnsafeCaptchaServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to CaptchaServiceServer will
// result in compilation errors.
type UnsafeCaptchaServiceServer interface {
mustEmbedUnimplementedCaptchaServiceServer()
}
func RegisterCaptchaServiceServer(s grpc.ServiceRegistrar, srv CaptchaServiceServer) {
// If the following call pancis, it indicates UnimplementedCaptchaServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&CaptchaService_ServiceDesc, srv)
}
func _CaptchaService_CheckCaptcha_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CheckCaptchaRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CaptchaServiceServer).CheckCaptcha(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: CaptchaService_CheckCaptcha_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CaptchaServiceServer).CheckCaptcha(ctx, req.(*CheckCaptchaRequest))
}
return interceptor(ctx, in, info, handler)
}
// CaptchaService_ServiceDesc is the grpc.ServiceDesc for CaptchaService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var CaptchaService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.CaptchaService",
HandlerType: (*CaptchaServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CheckCaptcha",
Handler: _CaptchaService_CheckCaptcha_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "captcha.proto",
}

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.1
// protoc v5.28.2
// protoc-gen-go v1.36.6
// protoc v5.29.3
// source: command.proto
package proto
@@ -11,6 +11,7 @@ import (
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
@@ -21,13 +22,12 @@ const (
)
type CommandInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Tags []string `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"`
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Tags []string `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *CommandInfo) Reset() {
@@ -82,12 +82,11 @@ func (x *CommandInfo) GetTags() []string {
}
type CommandLookupRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *CommandLookupRequest) Reset() {
@@ -135,11 +134,10 @@ func (x *CommandLookupRequest) GetMethod() string {
}
type AddCommandResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
unknownFields protoimpl.UnknownFields
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *AddCommandResponse) Reset() {
@@ -180,11 +178,10 @@ func (x *AddCommandResponse) GetIsSuccess() bool {
}
type RemoveCommandResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
unknownFields protoimpl.UnknownFields
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *RemoveCommandResponse) Reset() {
@@ -225,13 +222,12 @@ func (x *RemoveCommandResponse) GetIsSuccess() bool {
}
type CommandArgument struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Command string `protobuf:"bytes,1,opt,name=command,proto3" json:"command,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3,oneof" json:"payload,omitempty"`
unknownFields protoimpl.UnknownFields
Command string `protobuf:"bytes,1,opt,name=command,proto3" json:"command,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3,oneof" json:"payload,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *CommandArgument) Reset() {
@@ -286,14 +282,13 @@ func (x *CommandArgument) GetPayload() []byte {
}
type CommandReturn struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
IsDelivered bool `protobuf:"varint,1,opt,name=is_delivered,json=isDelivered,proto3" json:"is_delivered,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
ContentType string `protobuf:"bytes,3,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"`
Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3,oneof" json:"payload,omitempty"`
unknownFields protoimpl.UnknownFields
IsDelivered bool `protobuf:"varint,1,opt,name=is_delivered,json=isDelivered,proto3" json:"is_delivered,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
ContentType string `protobuf:"bytes,3,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"`
Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3,oneof" json:"payload,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *CommandReturn) Reset() {
@@ -356,71 +351,50 @@ func (x *CommandReturn) GetPayload() []byte {
var File_command_proto protoreflect.FileDescriptor
var file_command_proto_rawDesc = []byte{
0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x49, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x0a,
0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67,
0x73, 0x22, 0x3e, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x6f, 0x6f, 0x6b,
0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74,
0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f,
0x64, 0x22, 0x33, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75,
0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53,
0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x36, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x6e,
0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e,
0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d,
0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74,
0x68, 0x6f, 0x64, 0x12, 0x1d, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x88,
0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x98,
0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e,
0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65,
0x72, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20,
0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d,
0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48,
0x00, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a,
0x08, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0xa8, 0x02, 0x0a, 0x11, 0x43, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12,
0x3d, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x12, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x66,
0x6f, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x43, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c,
0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12,
0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c,
0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0b,
0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x75, 0x6d,
0x65, 0x6e, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
0x61, 0x6e, 0x64, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x11, 0x53,
0x65, 0x6e, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x00,
0x28, 0x01, 0x30, 0x01, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
const file_command_proto_rawDesc = "" +
"\n" +
"\rcommand.proto\x12\x05proto\"I\n" +
"\vCommandInfo\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" +
"\x06method\x18\x02 \x01(\tR\x06method\x12\x12\n" +
"\x04tags\x18\x03 \x03(\tR\x04tags\">\n" +
"\x14CommandLookupRequest\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" +
"\x06method\x18\x02 \x01(\tR\x06method\"3\n" +
"\x12AddCommandResponse\x12\x1d\n" +
"\n" +
"is_success\x18\x01 \x01(\bR\tisSuccess\"6\n" +
"\x15RemoveCommandResponse\x12\x1d\n" +
"\n" +
"is_success\x18\x01 \x01(\bR\tisSuccess\"n\n" +
"\x0fCommandArgument\x12\x18\n" +
"\acommand\x18\x01 \x01(\tR\acommand\x12\x16\n" +
"\x06method\x18\x02 \x01(\tR\x06method\x12\x1d\n" +
"\apayload\x18\x03 \x01(\fH\x00R\apayload\x88\x01\x01B\n" +
"\n" +
"\b_payload\"\x98\x01\n" +
"\rCommandReturn\x12!\n" +
"\fis_delivered\x18\x01 \x01(\bR\visDelivered\x12\x16\n" +
"\x06status\x18\x02 \x01(\x05R\x06status\x12!\n" +
"\fcontent_type\x18\x03 \x01(\tR\vcontentType\x12\x1d\n" +
"\apayload\x18\x04 \x01(\fH\x00R\apayload\x88\x01\x01B\n" +
"\n" +
"\b_payload2\xa6\x02\n" +
"\x0fCommandProvider\x12=\n" +
"\n" +
"AddCommand\x12\x12.proto.CommandInfo\x1a\x19.proto.AddCommandResponse\"\x00\x12L\n" +
"\rRemoveCommand\x12\x1b.proto.CommandLookupRequest\x1a\x1c.proto.RemoveCommandResponse\"\x00\x12=\n" +
"\vSendCommand\x12\x16.proto.CommandArgument\x1a\x14.proto.CommandReturn\"\x00\x12G\n" +
"\x11SendStreamCommand\x12\x16.proto.CommandArgument\x1a\x14.proto.CommandReturn\"\x00(\x010\x01B\tZ\a.;protob\x06proto3"
var (
file_command_proto_rawDescOnce sync.Once
file_command_proto_rawDescData = file_command_proto_rawDesc
file_command_proto_rawDescData []byte
)
func file_command_proto_rawDescGZIP() []byte {
file_command_proto_rawDescOnce.Do(func() {
file_command_proto_rawDescData = protoimpl.X.CompressGZIP(file_command_proto_rawDescData)
file_command_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_command_proto_rawDesc), len(file_command_proto_rawDesc)))
})
return file_command_proto_rawDescData
}
@@ -435,14 +409,14 @@ var file_command_proto_goTypes = []any{
(*CommandReturn)(nil), // 5: proto.CommandReturn
}
var file_command_proto_depIdxs = []int32{
0, // 0: proto.CommandController.AddCommand:input_type -> proto.CommandInfo
1, // 1: proto.CommandController.RemoveCommand:input_type -> proto.CommandLookupRequest
4, // 2: proto.CommandController.SendCommand:input_type -> proto.CommandArgument
4, // 3: proto.CommandController.SendStreamCommand:input_type -> proto.CommandArgument
2, // 4: proto.CommandController.AddCommand:output_type -> proto.AddCommandResponse
3, // 5: proto.CommandController.RemoveCommand:output_type -> proto.RemoveCommandResponse
5, // 6: proto.CommandController.SendCommand:output_type -> proto.CommandReturn
5, // 7: proto.CommandController.SendStreamCommand:output_type -> proto.CommandReturn
0, // 0: proto.CommandProvider.AddCommand:input_type -> proto.CommandInfo
1, // 1: proto.CommandProvider.RemoveCommand:input_type -> proto.CommandLookupRequest
4, // 2: proto.CommandProvider.SendCommand:input_type -> proto.CommandArgument
4, // 3: proto.CommandProvider.SendStreamCommand:input_type -> proto.CommandArgument
2, // 4: proto.CommandProvider.AddCommand:output_type -> proto.AddCommandResponse
3, // 5: proto.CommandProvider.RemoveCommand:output_type -> proto.RemoveCommandResponse
5, // 6: proto.CommandProvider.SendCommand:output_type -> proto.CommandReturn
5, // 7: proto.CommandProvider.SendStreamCommand:output_type -> proto.CommandReturn
4, // [4:8] is the sub-list for method output_type
0, // [0:4] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
@@ -461,7 +435,7 @@ func file_command_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_command_proto_rawDesc,
RawDescriptor: unsafe.Slice(unsafe.StringData(file_command_proto_rawDesc), len(file_command_proto_rawDesc)),
NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
@@ -472,7 +446,6 @@ func file_command_proto_init() {
MessageInfos: file_command_proto_msgTypes,
}.Build()
File_command_proto = out.File
file_command_proto_rawDesc = nil
file_command_proto_goTypes = nil
file_command_proto_depIdxs = nil
}

View File

@@ -4,7 +4,7 @@ option go_package = ".;proto";
package proto;
service CommandController {
service CommandProvider {
rpc AddCommand(CommandInfo) returns (AddCommandResponse) {}
rpc RemoveCommand(CommandLookupRequest) returns (RemoveCommandResponse) {}
rpc SendCommand(CommandArgument) returns (CommandReturn) {}

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v5.28.2
// - protoc v5.29.3
// source: command.proto
package proto
@@ -19,63 +19,63 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
CommandController_AddCommand_FullMethodName = "/proto.CommandController/AddCommand"
CommandController_RemoveCommand_FullMethodName = "/proto.CommandController/RemoveCommand"
CommandController_SendCommand_FullMethodName = "/proto.CommandController/SendCommand"
CommandController_SendStreamCommand_FullMethodName = "/proto.CommandController/SendStreamCommand"
CommandProvider_AddCommand_FullMethodName = "/proto.CommandProvider/AddCommand"
CommandProvider_RemoveCommand_FullMethodName = "/proto.CommandProvider/RemoveCommand"
CommandProvider_SendCommand_FullMethodName = "/proto.CommandProvider/SendCommand"
CommandProvider_SendStreamCommand_FullMethodName = "/proto.CommandProvider/SendStreamCommand"
)
// CommandControllerClient is the client API for CommandController service.
// CommandProviderClient is the client API for CommandProvider 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 CommandControllerClient interface {
type CommandProviderClient interface {
AddCommand(ctx context.Context, in *CommandInfo, opts ...grpc.CallOption) (*AddCommandResponse, error)
RemoveCommand(ctx context.Context, in *CommandLookupRequest, opts ...grpc.CallOption) (*RemoveCommandResponse, error)
SendCommand(ctx context.Context, in *CommandArgument, opts ...grpc.CallOption) (*CommandReturn, error)
SendStreamCommand(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[CommandArgument, CommandReturn], error)
}
type commandControllerClient struct {
type commandProviderClient struct {
cc grpc.ClientConnInterface
}
func NewCommandControllerClient(cc grpc.ClientConnInterface) CommandControllerClient {
return &commandControllerClient{cc}
func NewCommandProviderClient(cc grpc.ClientConnInterface) CommandProviderClient {
return &commandProviderClient{cc}
}
func (c *commandControllerClient) AddCommand(ctx context.Context, in *CommandInfo, opts ...grpc.CallOption) (*AddCommandResponse, error) {
func (c *commandProviderClient) AddCommand(ctx context.Context, in *CommandInfo, opts ...grpc.CallOption) (*AddCommandResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AddCommandResponse)
err := c.cc.Invoke(ctx, CommandController_AddCommand_FullMethodName, in, out, cOpts...)
err := c.cc.Invoke(ctx, CommandProvider_AddCommand_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *commandControllerClient) RemoveCommand(ctx context.Context, in *CommandLookupRequest, opts ...grpc.CallOption) (*RemoveCommandResponse, error) {
func (c *commandProviderClient) RemoveCommand(ctx context.Context, in *CommandLookupRequest, opts ...grpc.CallOption) (*RemoveCommandResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RemoveCommandResponse)
err := c.cc.Invoke(ctx, CommandController_RemoveCommand_FullMethodName, in, out, cOpts...)
err := c.cc.Invoke(ctx, CommandProvider_RemoveCommand_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *commandControllerClient) SendCommand(ctx context.Context, in *CommandArgument, opts ...grpc.CallOption) (*CommandReturn, error) {
func (c *commandProviderClient) SendCommand(ctx context.Context, in *CommandArgument, opts ...grpc.CallOption) (*CommandReturn, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CommandReturn)
err := c.cc.Invoke(ctx, CommandController_SendCommand_FullMethodName, in, out, cOpts...)
err := c.cc.Invoke(ctx, CommandProvider_SendCommand_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *commandControllerClient) SendStreamCommand(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[CommandArgument, CommandReturn], error) {
func (c *commandProviderClient) SendStreamCommand(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[CommandArgument, CommandReturn], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &CommandController_ServiceDesc.Streams[0], CommandController_SendStreamCommand_FullMethodName, cOpts...)
stream, err := c.cc.NewStream(ctx, &CommandProvider_ServiceDesc.Streams[0], CommandProvider_SendStreamCommand_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
@@ -84,144 +84,144 @@ func (c *commandControllerClient) SendStreamCommand(ctx context.Context, opts ..
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type CommandController_SendStreamCommandClient = grpc.BidiStreamingClient[CommandArgument, CommandReturn]
type CommandProvider_SendStreamCommandClient = grpc.BidiStreamingClient[CommandArgument, CommandReturn]
// CommandControllerServer is the server API for CommandController service.
// All implementations must embed UnimplementedCommandControllerServer
// CommandProviderServer is the server API for CommandProvider service.
// All implementations must embed UnimplementedCommandProviderServer
// for forward compatibility.
type CommandControllerServer interface {
type CommandProviderServer interface {
AddCommand(context.Context, *CommandInfo) (*AddCommandResponse, error)
RemoveCommand(context.Context, *CommandLookupRequest) (*RemoveCommandResponse, error)
SendCommand(context.Context, *CommandArgument) (*CommandReturn, error)
SendStreamCommand(grpc.BidiStreamingServer[CommandArgument, CommandReturn]) error
mustEmbedUnimplementedCommandControllerServer()
mustEmbedUnimplementedCommandProviderServer()
}
// UnimplementedCommandControllerServer must be embedded to have
// UnimplementedCommandProviderServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedCommandControllerServer struct{}
type UnimplementedCommandProviderServer struct{}
func (UnimplementedCommandControllerServer) AddCommand(context.Context, *CommandInfo) (*AddCommandResponse, error) {
func (UnimplementedCommandProviderServer) AddCommand(context.Context, *CommandInfo) (*AddCommandResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AddCommand not implemented")
}
func (UnimplementedCommandControllerServer) RemoveCommand(context.Context, *CommandLookupRequest) (*RemoveCommandResponse, error) {
func (UnimplementedCommandProviderServer) RemoveCommand(context.Context, *CommandLookupRequest) (*RemoveCommandResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RemoveCommand not implemented")
}
func (UnimplementedCommandControllerServer) SendCommand(context.Context, *CommandArgument) (*CommandReturn, error) {
func (UnimplementedCommandProviderServer) SendCommand(context.Context, *CommandArgument) (*CommandReturn, error) {
return nil, status.Errorf(codes.Unimplemented, "method SendCommand not implemented")
}
func (UnimplementedCommandControllerServer) SendStreamCommand(grpc.BidiStreamingServer[CommandArgument, CommandReturn]) error {
func (UnimplementedCommandProviderServer) SendStreamCommand(grpc.BidiStreamingServer[CommandArgument, CommandReturn]) error {
return status.Errorf(codes.Unimplemented, "method SendStreamCommand not implemented")
}
func (UnimplementedCommandControllerServer) mustEmbedUnimplementedCommandControllerServer() {}
func (UnimplementedCommandControllerServer) testEmbeddedByValue() {}
func (UnimplementedCommandProviderServer) mustEmbedUnimplementedCommandProviderServer() {}
func (UnimplementedCommandProviderServer) testEmbeddedByValue() {}
// UnsafeCommandControllerServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to CommandControllerServer will
// UnsafeCommandProviderServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to CommandProviderServer will
// result in compilation errors.
type UnsafeCommandControllerServer interface {
mustEmbedUnimplementedCommandControllerServer()
type UnsafeCommandProviderServer interface {
mustEmbedUnimplementedCommandProviderServer()
}
func RegisterCommandControllerServer(s grpc.ServiceRegistrar, srv CommandControllerServer) {
// If the following call pancis, it indicates UnimplementedCommandControllerServer was
func RegisterCommandProviderServer(s grpc.ServiceRegistrar, srv CommandProviderServer) {
// If the following call pancis, it indicates UnimplementedCommandProviderServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&CommandController_ServiceDesc, srv)
s.RegisterService(&CommandProvider_ServiceDesc, srv)
}
func _CommandController_AddCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
func _CommandProvider_AddCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CommandInfo)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CommandControllerServer).AddCommand(ctx, in)
return srv.(CommandProviderServer).AddCommand(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: CommandController_AddCommand_FullMethodName,
FullMethod: CommandProvider_AddCommand_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CommandControllerServer).AddCommand(ctx, req.(*CommandInfo))
return srv.(CommandProviderServer).AddCommand(ctx, req.(*CommandInfo))
}
return interceptor(ctx, in, info, handler)
}
func _CommandController_RemoveCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
func _CommandProvider_RemoveCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CommandLookupRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CommandControllerServer).RemoveCommand(ctx, in)
return srv.(CommandProviderServer).RemoveCommand(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: CommandController_RemoveCommand_FullMethodName,
FullMethod: CommandProvider_RemoveCommand_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CommandControllerServer).RemoveCommand(ctx, req.(*CommandLookupRequest))
return srv.(CommandProviderServer).RemoveCommand(ctx, req.(*CommandLookupRequest))
}
return interceptor(ctx, in, info, handler)
}
func _CommandController_SendCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
func _CommandProvider_SendCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CommandArgument)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CommandControllerServer).SendCommand(ctx, in)
return srv.(CommandProviderServer).SendCommand(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: CommandController_SendCommand_FullMethodName,
FullMethod: CommandProvider_SendCommand_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CommandControllerServer).SendCommand(ctx, req.(*CommandArgument))
return srv.(CommandProviderServer).SendCommand(ctx, req.(*CommandArgument))
}
return interceptor(ctx, in, info, handler)
}
func _CommandController_SendStreamCommand_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(CommandControllerServer).SendStreamCommand(&grpc.GenericServerStream[CommandArgument, CommandReturn]{ServerStream: stream})
func _CommandProvider_SendStreamCommand_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(CommandProviderServer).SendStreamCommand(&grpc.GenericServerStream[CommandArgument, CommandReturn]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type CommandController_SendStreamCommandServer = grpc.BidiStreamingServer[CommandArgument, CommandReturn]
type CommandProvider_SendStreamCommandServer = grpc.BidiStreamingServer[CommandArgument, CommandReturn]
// CommandController_ServiceDesc is the grpc.ServiceDesc for CommandController service.
// CommandProvider_ServiceDesc is the grpc.ServiceDesc for CommandProvider service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var CommandController_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.CommandController",
HandlerType: (*CommandControllerServer)(nil),
var CommandProvider_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.CommandProvider",
HandlerType: (*CommandProviderServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "AddCommand",
Handler: _CommandController_AddCommand_Handler,
Handler: _CommandProvider_AddCommand_Handler,
},
{
MethodName: "RemoveCommand",
Handler: _CommandController_RemoveCommand_Handler,
Handler: _CommandProvider_RemoveCommand_Handler,
},
{
MethodName: "SendCommand",
Handler: _CommandController_SendCommand_Handler,
Handler: _CommandProvider_SendCommand_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "SendStreamCommand",
Handler: _CommandController_SendStreamCommand_Handler,
Handler: _CommandProvider_SendStreamCommand_Handler,
ServerStreams: true,
ClientStreams: true,
},

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.1
// protoc v5.28.2
// protoc-gen-go v1.36.6
// protoc v5.29.3
// source: database.proto
package proto
@@ -11,6 +11,7 @@ import (
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
@@ -21,11 +22,10 @@ const (
)
type AllocDatabaseRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *AllocDatabaseRequest) Reset() {
@@ -66,12 +66,11 @@ func (x *AllocDatabaseRequest) GetName() string {
}
type AllocDatabaseResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
Dsn string `protobuf:"bytes,2,opt,name=dsn,proto3" json:"dsn,omitempty"`
unknownFields protoimpl.UnknownFields
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
Dsn string `protobuf:"bytes,2,opt,name=dsn,proto3" json:"dsn,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *AllocDatabaseResponse) Reset() {
@@ -120,34 +119,26 @@ func (x *AllocDatabaseResponse) GetDsn() string {
var File_database_proto protoreflect.FileDescriptor
var file_database_proto_rawDesc = []byte{
0x0a, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2a, 0x0a, 0x14, 0x41, 0x6c, 0x6c, 0x6f, 0x63,
0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x22, 0x48, 0x0a, 0x15, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x44, 0x61, 0x74, 0x61,
0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
0x69, 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64,
0x73, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x73, 0x6e, 0x32, 0x62, 0x0a,
0x12, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x6c, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x0d, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x44, 0x61, 0x74, 0x61,
0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x6c, 0x6c,
0x6f, 0x63, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x44,
0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
const file_database_proto_rawDesc = "" +
"\n" +
"\x0edatabase.proto\x12\x05proto\"*\n" +
"\x14AllocDatabaseRequest\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\"H\n" +
"\x15AllocDatabaseResponse\x12\x1d\n" +
"\n" +
"is_success\x18\x01 \x01(\bR\tisSuccess\x12\x10\n" +
"\x03dsn\x18\x02 \x01(\tR\x03dsn2_\n" +
"\x0fDatabaseService\x12L\n" +
"\rAllocDatabase\x12\x1b.proto.AllocDatabaseRequest\x1a\x1c.proto.AllocDatabaseResponse\"\x00B\tZ\a.;protob\x06proto3"
var (
file_database_proto_rawDescOnce sync.Once
file_database_proto_rawDescData = file_database_proto_rawDesc
file_database_proto_rawDescData []byte
)
func file_database_proto_rawDescGZIP() []byte {
file_database_proto_rawDescOnce.Do(func() {
file_database_proto_rawDescData = protoimpl.X.CompressGZIP(file_database_proto_rawDescData)
file_database_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_database_proto_rawDesc), len(file_database_proto_rawDesc)))
})
return file_database_proto_rawDescData
}
@@ -158,8 +149,8 @@ var file_database_proto_goTypes = []any{
(*AllocDatabaseResponse)(nil), // 1: proto.AllocDatabaseResponse
}
var file_database_proto_depIdxs = []int32{
0, // 0: proto.DatabaseController.AllocDatabase:input_type -> proto.AllocDatabaseRequest
1, // 1: proto.DatabaseController.AllocDatabase:output_type -> proto.AllocDatabaseResponse
0, // 0: proto.DatabaseService.AllocDatabase:input_type -> proto.AllocDatabaseRequest
1, // 1: proto.DatabaseService.AllocDatabase:output_type -> proto.AllocDatabaseResponse
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
@@ -176,7 +167,7 @@ func file_database_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_database_proto_rawDesc,
RawDescriptor: unsafe.Slice(unsafe.StringData(file_database_proto_rawDesc), len(file_database_proto_rawDesc)),
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
@@ -187,7 +178,6 @@ func file_database_proto_init() {
MessageInfos: file_database_proto_msgTypes,
}.Build()
File_database_proto = out.File
file_database_proto_rawDesc = nil
file_database_proto_goTypes = nil
file_database_proto_depIdxs = nil
}

View File

@@ -4,7 +4,7 @@ option go_package = ".;proto";
package proto;
service DatabaseController {
service DatabaseService {
rpc AllocDatabase(AllocDatabaseRequest) returns (AllocDatabaseResponse) {}
}

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v5.28.2
// - protoc v5.29.3
// source: database.proto
package proto
@@ -19,101 +19,101 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
DatabaseController_AllocDatabase_FullMethodName = "/proto.DatabaseController/AllocDatabase"
DatabaseService_AllocDatabase_FullMethodName = "/proto.DatabaseService/AllocDatabase"
)
// DatabaseControllerClient is the client API for DatabaseController service.
// DatabaseServiceClient is the client API for DatabaseService 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 DatabaseControllerClient interface {
type DatabaseServiceClient interface {
AllocDatabase(ctx context.Context, in *AllocDatabaseRequest, opts ...grpc.CallOption) (*AllocDatabaseResponse, error)
}
type databaseControllerClient struct {
type databaseServiceClient struct {
cc grpc.ClientConnInterface
}
func NewDatabaseControllerClient(cc grpc.ClientConnInterface) DatabaseControllerClient {
return &databaseControllerClient{cc}
func NewDatabaseServiceClient(cc grpc.ClientConnInterface) DatabaseServiceClient {
return &databaseServiceClient{cc}
}
func (c *databaseControllerClient) AllocDatabase(ctx context.Context, in *AllocDatabaseRequest, opts ...grpc.CallOption) (*AllocDatabaseResponse, error) {
func (c *databaseServiceClient) AllocDatabase(ctx context.Context, in *AllocDatabaseRequest, opts ...grpc.CallOption) (*AllocDatabaseResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AllocDatabaseResponse)
err := c.cc.Invoke(ctx, DatabaseController_AllocDatabase_FullMethodName, in, out, cOpts...)
err := c.cc.Invoke(ctx, DatabaseService_AllocDatabase_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// DatabaseControllerServer is the server API for DatabaseController service.
// All implementations must embed UnimplementedDatabaseControllerServer
// DatabaseServiceServer is the server API for DatabaseService service.
// All implementations must embed UnimplementedDatabaseServiceServer
// for forward compatibility.
type DatabaseControllerServer interface {
type DatabaseServiceServer interface {
AllocDatabase(context.Context, *AllocDatabaseRequest) (*AllocDatabaseResponse, error)
mustEmbedUnimplementedDatabaseControllerServer()
mustEmbedUnimplementedDatabaseServiceServer()
}
// UnimplementedDatabaseControllerServer must be embedded to have
// UnimplementedDatabaseServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedDatabaseControllerServer struct{}
type UnimplementedDatabaseServiceServer struct{}
func (UnimplementedDatabaseControllerServer) AllocDatabase(context.Context, *AllocDatabaseRequest) (*AllocDatabaseResponse, error) {
func (UnimplementedDatabaseServiceServer) AllocDatabase(context.Context, *AllocDatabaseRequest) (*AllocDatabaseResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AllocDatabase not implemented")
}
func (UnimplementedDatabaseControllerServer) mustEmbedUnimplementedDatabaseControllerServer() {}
func (UnimplementedDatabaseControllerServer) testEmbeddedByValue() {}
func (UnimplementedDatabaseServiceServer) mustEmbedUnimplementedDatabaseServiceServer() {}
func (UnimplementedDatabaseServiceServer) testEmbeddedByValue() {}
// UnsafeDatabaseControllerServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to DatabaseControllerServer will
// UnsafeDatabaseServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to DatabaseServiceServer will
// result in compilation errors.
type UnsafeDatabaseControllerServer interface {
mustEmbedUnimplementedDatabaseControllerServer()
type UnsafeDatabaseServiceServer interface {
mustEmbedUnimplementedDatabaseServiceServer()
}
func RegisterDatabaseControllerServer(s grpc.ServiceRegistrar, srv DatabaseControllerServer) {
// If the following call pancis, it indicates UnimplementedDatabaseControllerServer was
func RegisterDatabaseServiceServer(s grpc.ServiceRegistrar, srv DatabaseServiceServer) {
// If the following call pancis, it indicates UnimplementedDatabaseServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&DatabaseController_ServiceDesc, srv)
s.RegisterService(&DatabaseService_ServiceDesc, srv)
}
func _DatabaseController_AllocDatabase_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
func _DatabaseService_AllocDatabase_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AllocDatabaseRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(DatabaseControllerServer).AllocDatabase(ctx, in)
return srv.(DatabaseServiceServer).AllocDatabase(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: DatabaseController_AllocDatabase_FullMethodName,
FullMethod: DatabaseService_AllocDatabase_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(DatabaseControllerServer).AllocDatabase(ctx, req.(*AllocDatabaseRequest))
return srv.(DatabaseServiceServer).AllocDatabase(ctx, req.(*AllocDatabaseRequest))
}
return interceptor(ctx, in, info, handler)
}
// DatabaseController_ServiceDesc is the grpc.ServiceDesc for DatabaseController service.
// DatabaseService_ServiceDesc is the grpc.ServiceDesc for DatabaseService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var DatabaseController_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.DatabaseController",
HandlerType: (*DatabaseControllerServer)(nil),
var DatabaseService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "proto.DatabaseService",
HandlerType: (*DatabaseServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "AllocDatabase",
Handler: _DatabaseController_AllocDatabase_Handler,
Handler: _DatabaseService_AllocDatabase_Handler,
},
},
Streams: []grpc.StreamDesc{},

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.1
// protoc v5.28.2
// protoc-gen-go v1.36.6
// protoc v5.29.3
// source: services.proto
package proto
@@ -11,6 +11,7 @@ import (
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
@@ -21,15 +22,14 @@ const (
)
type ServiceInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"`
GrpcAddr string `protobuf:"bytes,4,opt,name=grpc_addr,json=grpcAddr,proto3" json:"grpc_addr,omitempty"`
HttpAddr *string `protobuf:"bytes,5,opt,name=http_addr,json=httpAddr,proto3,oneof" json:"http_addr,omitempty"`
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"`
GrpcAddr string `protobuf:"bytes,4,opt,name=grpc_addr,json=grpcAddr,proto3" json:"grpc_addr,omitempty"`
HttpAddr *string `protobuf:"bytes,5,opt,name=http_addr,json=httpAddr,proto3,oneof" json:"http_addr,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *ServiceInfo) Reset() {
@@ -98,12 +98,11 @@ func (x *ServiceInfo) GetHttpAddr() string {
}
type GetServiceRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Id *string `protobuf:"bytes,1,opt,name=id,proto3,oneof" json:"id,omitempty"`
Type *string `protobuf:"bytes,2,opt,name=type,proto3,oneof" json:"type,omitempty"`
unknownFields protoimpl.UnknownFields
Id *string `protobuf:"bytes,1,opt,name=id,proto3,oneof" json:"id,omitempty"`
Type *string `protobuf:"bytes,2,opt,name=type,proto3,oneof" json:"type,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *GetServiceRequest) Reset() {
@@ -151,11 +150,10 @@ func (x *GetServiceRequest) GetType() string {
}
type GetServiceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Data *ServiceInfo `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
unknownFields protoimpl.UnknownFields
Data *ServiceInfo `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *GetServiceResponse) Reset() {
@@ -196,11 +194,10 @@ func (x *GetServiceResponse) GetData() *ServiceInfo {
}
type ListServiceRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Type *string `protobuf:"bytes,1,opt,name=type,proto3,oneof" json:"type,omitempty"`
unknownFields protoimpl.UnknownFields
Type *string `protobuf:"bytes,1,opt,name=type,proto3,oneof" json:"type,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *ListServiceRequest) Reset() {
@@ -241,11 +238,10 @@ func (x *ListServiceRequest) GetType() string {
}
type ListServiceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Data []*ServiceInfo `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
unknownFields protoimpl.UnknownFields
Data []*ServiceInfo `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *ListServiceResponse) Reset() {
@@ -286,11 +282,10 @@ func (x *ListServiceResponse) GetData() []*ServiceInfo {
}
type AddServiceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
unknownFields protoimpl.UnknownFields
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *AddServiceResponse) Reset() {
@@ -331,11 +326,10 @@ func (x *AddServiceResponse) GetIsSuccess() bool {
}
type RemoveServiceRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *RemoveServiceRequest) Reset() {
@@ -376,11 +370,10 @@ func (x *RemoveServiceRequest) GetId() string {
}
type RemoveServiceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
unknownFields protoimpl.UnknownFields
IsSuccess bool `protobuf:"varint,1,opt,name=is_success,json=isSuccess,proto3" json:"is_success,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *RemoveServiceResponse) Reset() {
@@ -421,12 +414,11 @@ func (x *RemoveServiceResponse) GetIsSuccess() bool {
}
type EventInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Event string `protobuf:"bytes,1,opt,name=event,proto3" json:"event,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
unknownFields protoimpl.UnknownFields
Event string `protobuf:"bytes,1,opt,name=event,proto3" json:"event,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *EventInfo) Reset() {
@@ -474,9 +466,9 @@ func (x *EventInfo) GetData() []byte {
}
type EventResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *EventResponse) Reset() {
@@ -511,83 +503,58 @@ func (*EventResponse) Descriptor() ([]byte, []int) {
var File_services_proto protoreflect.FileDescriptor
var file_services_proto_rawDesc = []byte{
0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x94, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c,
0x61, 0x62, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65,
0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x72, 0x70, 0x63, 0x41, 0x64, 0x64, 0x72, 0x12, 0x20,
0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28,
0x09, 0x48, 0x00, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x41, 0x64, 0x64, 0x72, 0x88, 0x01, 0x01,
0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x22, 0x51,
0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48,
0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x88, 0x01,
0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x74, 0x79, 0x70,
0x65, 0x22, 0x3c, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22,
0x36, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x42, 0x07,
0x0a, 0x05, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3d, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26,
0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f,
0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x33, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
0x69, 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x26, 0x0a, 0x14, 0x52,
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x02, 0x69, 0x64, 0x22, 0x36, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
0x69, 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x35, 0x0a, 0x09, 0x45,
0x76, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12,
0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61,
0x74, 0x61, 0x22, 0x0f, 0x0a, 0x0d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x32, 0xe8, 0x02, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44,
0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x43, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47,
0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a,
0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x19, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x45,
0x76, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x76, 0x65,
0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45,
0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x09,
0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
const file_services_proto_rawDesc = "" +
"\n" +
"\x0eservices.proto\x12\x05proto\"\x94\x01\n" +
"\vServiceInfo\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
"\x04type\x18\x02 \x01(\tR\x04type\x12\x14\n" +
"\x05label\x18\x03 \x01(\tR\x05label\x12\x1b\n" +
"\tgrpc_addr\x18\x04 \x01(\tR\bgrpcAddr\x12 \n" +
"\thttp_addr\x18\x05 \x01(\tH\x00R\bhttpAddr\x88\x01\x01B\f\n" +
"\n" +
"_http_addr\"Q\n" +
"\x11GetServiceRequest\x12\x13\n" +
"\x02id\x18\x01 \x01(\tH\x00R\x02id\x88\x01\x01\x12\x17\n" +
"\x04type\x18\x02 \x01(\tH\x01R\x04type\x88\x01\x01B\x05\n" +
"\x03_idB\a\n" +
"\x05_type\"<\n" +
"\x12GetServiceResponse\x12&\n" +
"\x04data\x18\x01 \x01(\v2\x12.proto.ServiceInfoR\x04data\"6\n" +
"\x12ListServiceRequest\x12\x17\n" +
"\x04type\x18\x01 \x01(\tH\x00R\x04type\x88\x01\x01B\a\n" +
"\x05_type\"=\n" +
"\x13ListServiceResponse\x12&\n" +
"\x04data\x18\x01 \x03(\v2\x12.proto.ServiceInfoR\x04data\"3\n" +
"\x12AddServiceResponse\x12\x1d\n" +
"\n" +
"is_success\x18\x01 \x01(\bR\tisSuccess\"&\n" +
"\x14RemoveServiceRequest\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\"6\n" +
"\x15RemoveServiceResponse\x12\x1d\n" +
"\n" +
"is_success\x18\x01 \x01(\bR\tisSuccess\"5\n" +
"\tEventInfo\x12\x14\n" +
"\x05event\x18\x01 \x01(\tR\x05event\x12\x12\n" +
"\x04data\x18\x02 \x01(\fR\x04data\"\x0f\n" +
"\rEventResponse2\xe8\x02\n" +
"\x10DirectoryService\x12C\n" +
"\n" +
"GetService\x12\x18.proto.GetServiceRequest\x1a\x19.proto.GetServiceResponse\"\x00\x12F\n" +
"\vListService\x12\x19.proto.ListServiceRequest\x1a\x1a.proto.ListServiceResponse\"\x00\x12=\n" +
"\n" +
"AddService\x12\x12.proto.ServiceInfo\x1a\x19.proto.AddServiceResponse\"\x00\x12L\n" +
"\rRemoveService\x12\x1b.proto.RemoveServiceRequest\x1a\x1c.proto.RemoveServiceResponse\"\x00\x12:\n" +
"\x0eBroadcastEvent\x12\x10.proto.EventInfo\x1a\x14.proto.EventResponse\"\x00B\tZ\a.;protob\x06proto3"
var (
file_services_proto_rawDescOnce sync.Once
file_services_proto_rawDescData = file_services_proto_rawDesc
file_services_proto_rawDescData []byte
)
func file_services_proto_rawDescGZIP() []byte {
file_services_proto_rawDescOnce.Do(func() {
file_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_services_proto_rawDescData)
file_services_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_services_proto_rawDesc), len(file_services_proto_rawDesc)))
})
return file_services_proto_rawDescData
}
@@ -608,16 +575,16 @@ var file_services_proto_goTypes = []any{
var file_services_proto_depIdxs = []int32{
0, // 0: proto.GetServiceResponse.data:type_name -> proto.ServiceInfo
0, // 1: proto.ListServiceResponse.data:type_name -> proto.ServiceInfo
1, // 2: proto.ServiceDirectory.GetService:input_type -> proto.GetServiceRequest
3, // 3: proto.ServiceDirectory.ListService:input_type -> proto.ListServiceRequest
0, // 4: proto.ServiceDirectory.AddService:input_type -> proto.ServiceInfo
6, // 5: proto.ServiceDirectory.RemoveService:input_type -> proto.RemoveServiceRequest
8, // 6: proto.ServiceDirectory.BroadcastEvent:input_type -> proto.EventInfo
2, // 7: proto.ServiceDirectory.GetService:output_type -> proto.GetServiceResponse
4, // 8: proto.ServiceDirectory.ListService:output_type -> proto.ListServiceResponse
5, // 9: proto.ServiceDirectory.AddService:output_type -> proto.AddServiceResponse
7, // 10: proto.ServiceDirectory.RemoveService:output_type -> proto.RemoveServiceResponse
9, // 11: proto.ServiceDirectory.BroadcastEvent:output_type -> proto.EventResponse
1, // 2: proto.DirectoryService.GetService:input_type -> proto.GetServiceRequest
3, // 3: proto.DirectoryService.ListService:input_type -> proto.ListServiceRequest
0, // 4: proto.DirectoryService.AddService:input_type -> proto.ServiceInfo
6, // 5: proto.DirectoryService.RemoveService:input_type -> proto.RemoveServiceRequest
8, // 6: proto.DirectoryService.BroadcastEvent:input_type -> proto.EventInfo
2, // 7: proto.DirectoryService.GetService:output_type -> proto.GetServiceResponse
4, // 8: proto.DirectoryService.ListService:output_type -> proto.ListServiceResponse
5, // 9: proto.DirectoryService.AddService:output_type -> proto.AddServiceResponse
7, // 10: proto.DirectoryService.RemoveService:output_type -> proto.RemoveServiceResponse
9, // 11: proto.DirectoryService.BroadcastEvent:output_type -> proto.EventResponse
7, // [7:12] is the sub-list for method output_type
2, // [2:7] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
@@ -637,7 +604,7 @@ func file_services_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_services_proto_rawDesc,
RawDescriptor: unsafe.Slice(unsafe.StringData(file_services_proto_rawDesc), len(file_services_proto_rawDesc)),
NumEnums: 0,
NumMessages: 10,
NumExtensions: 0,
@@ -648,7 +615,6 @@ func file_services_proto_init() {
MessageInfos: file_services_proto_msgTypes,
}.Build()
File_services_proto = out.File
file_services_proto_rawDesc = nil
file_services_proto_goTypes = nil
file_services_proto_depIdxs = nil
}

View File

@@ -4,7 +4,7 @@ option go_package = ".;proto";
package proto;
service ServiceDirectory {
service DirectoryService {
rpc GetService(GetServiceRequest) returns (GetServiceResponse) {}
rpc ListService(ListServiceRequest) returns (ListServiceResponse) {}
rpc AddService(ServiceInfo) returns (AddServiceResponse) {}

Some files were not shown because too many files have changed in this diff Show More