grpc auth

This commit is contained in:
royalcat 2024-10-10 19:23:59 +03:00
parent 12e3e605af
commit 87d4c13407
10 changed files with 449 additions and 48 deletions

5
cmd/controller/main.go Normal file
View file

@ -0,0 +1,5 @@
package main
func main() {
}

12
go.mod
View file

@ -3,9 +3,15 @@ module vpn.konfa.ch/controller
go 1.23.2 go 1.23.2
require ( require (
connectrpc.com/authn v0.2.0
connectrpc.com/connect v1.17.0 connectrpc.com/connect v1.17.0
github.com/bufbuild/buf v1.45.0 github.com/bufbuild/buf v1.45.0
github.com/carlmjohnson/requests v0.24.2 github.com/carlmjohnson/requests v0.24.2
github.com/coreos/go-oidc/v3 v3.11.0
github.com/knadh/koanf/providers/env v1.0.0
github.com/knadh/koanf/v2 v2.1.1
golang.org/x/net v0.30.0
golang.org/x/oauth2 v0.22.0
google.golang.org/protobuf v1.35.1 google.golang.org/protobuf v1.35.1
) )
@ -46,9 +52,11 @@ require (
github.com/felixge/fgprof v0.9.5 // indirect github.com/felixge/fgprof v0.9.5 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-chi/chi/v5 v5.1.0 // indirect github.com/go-chi/chi/v5 v5.1.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect
github.com/gofrs/flock v0.12.1 // indirect github.com/gofrs/flock v0.12.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@ -60,8 +68,11 @@ require (
github.com/jdx/go-netrc v1.0.0 // indirect github.com/jdx/go-netrc v1.0.0 // indirect
github.com/klauspost/compress v1.17.10 // indirect github.com/klauspost/compress v1.17.10 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect github.com/klauspost/pgzip v1.2.6 // indirect
github.com/knadh/koanf/maps v0.1.1 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/locker v1.0.1 // indirect github.com/moby/locker v1.0.1 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/patternmatcher v0.6.0 // indirect
@ -109,7 +120,6 @@ require (
golang.org/x/crypto v0.28.0 // indirect golang.org/x/crypto v0.28.0 // indirect
golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 // indirect golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 // indirect
golang.org/x/mod v0.21.0 // indirect golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sync v0.8.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect golang.org/x/term v0.25.0 // indirect

20
go.sum
View file

@ -15,6 +15,8 @@ buf.build/go/protoyaml v0.2.0/go.mod h1:L/9QvTDkTWcDTzAL6HMfN+mYC6CmZRm2KnsUA054
buf.build/go/spdx v0.2.0 h1:IItqM0/cMxvFJJumcBuP8NrsIzMs/UYjp/6WSpq8LTw= buf.build/go/spdx v0.2.0 h1:IItqM0/cMxvFJJumcBuP8NrsIzMs/UYjp/6WSpq8LTw=
buf.build/go/spdx v0.2.0/go.mod h1:bXdwQFem9Si3nsbNy8aJKGPoaPi5DKwdeEp5/ArZ6w8= buf.build/go/spdx v0.2.0/go.mod h1:bXdwQFem9Si3nsbNy8aJKGPoaPi5DKwdeEp5/ArZ6w8=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
connectrpc.com/authn v0.2.0 h1:epZK23EG7GP062dNn34wnhZfREcCXDzIu2nlocva9r8=
connectrpc.com/authn v0.2.0/go.mod h1:R9qxaacWwJVNuQWYyh7lJgEhBZ/w9NqvA4ivxOgw8x0=
connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk=
connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8=
connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY=
@ -72,6 +74,8 @@ github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oL
github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso=
github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g=
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@ -107,6 +111,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@ -114,6 +120,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c=
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
@ -171,6 +179,12 @@ github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/N
github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs=
github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
github.com/knadh/koanf/providers/env v1.0.0 h1:ufePaI9BnWH+ajuxGGiJ8pdTG0uLEUWC7/HDDPGLah0=
github.com/knadh/koanf/providers/env v1.0.0/go.mod h1:mzFyRZueYhb37oPmC1HAv/oGEEuyvJDA98r3XAa8Gak=
github.com/knadh/koanf/v2 v2.1.1 h1:/R8eXqasSTsmDCsAyYj+81Wteg8AqrV9CP6gvsTsOmM=
github.com/knadh/koanf/v2 v2.1.1/go.mod h1:4mnTRbZCK+ALuBXHZMjDfG9y714L7TykVnZkXbMU3Es=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -179,8 +193,12 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 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-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 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/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@ -329,6 +347,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View file

@ -3,8 +3,8 @@ syntax = "proto3";
package vpn.v1; package vpn.v1;
message CreateProfileRequest { message CreateProfileRequest {
string flavor_id = 1; string name = 1;
string name = 2; string flavor_id = 2;
} }
message CreateProfileResponse { message CreateProfileResponse {
@ -28,7 +28,23 @@ message Flavor {
string description = 3; string description = 3;
} }
message ListProfilesRequest {
}
message ListProfilesResponse {
repeated Profile profiles = 1;
}
message Profile {
string id = 1;
string name = 2;
string flavor_id = 3;
string connection_string = 4;
}
service ProfilesService { service ProfilesService {
rpc AvaliableFlavors(AvaliableFlavorsRequest) returns (AvaliableFlavorsResponse) {} rpc AvaliableFlavors(AvaliableFlavorsRequest) returns (AvaliableFlavorsResponse) {}
rpc CreateProfile(CreateProfileRequest) returns (CreateProfileResponse) {} rpc CreateProfile(CreateProfileRequest) returns (CreateProfileResponse) {}
rpc ListProfiles(ListProfilesRequest) returns (ListProfilesResponse) {}
} }

43
src/config/config.go Normal file
View file

@ -0,0 +1,43 @@
package config
import (
"strings"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/v2"
)
var k = koanf.New(".")
func Parse(path string) (config Config, err error) {
const envPrefix = ""
err = k.Load(env.Provider(envPrefix, ".",
func(s string) string {
key := strings.TrimPrefix(s, envPrefix)
key = strings.ReplaceAll(key, "_", ".")
return key
},
), nil)
if err != nil {
return config, err
}
err = k.Unmarshal("", &config)
if err != nil {
return config, err
}
return config, nil
}
type Config struct {
Listen string
Auth OIDC
}
type OIDC struct {
Issuer string
ClientID string
ClientSecret string
RedirectURL string
}

View file

@ -0,0 +1,57 @@
package grpcserver
import (
"context"
"errors"
"net/http"
"github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2"
)
func oidcAuth(provider *oidc.Provider, clientID, clientSecret, redirectURL string) func(ctx context.Context, req *http.Request) (any, error) {
verifier := provider.Verifier(&oidc.Config{ClientID: clientID})
// Configure an OpenID Connect aware OAuth2 client.
oauth2Config := oauth2.Config{
ClientID: clientID,
ClientSecret: clientSecret,
RedirectURL: redirectURL,
// Discovery returns the OAuth2 endpoints.
Endpoint: provider.Endpoint(),
// "openid" is a required scope for OpenID Connect flows.
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
}
return func(ctx context.Context, r *http.Request) (any, error) {
oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
if err != nil {
return nil, err
}
// Extract the ID Token from OAuth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
return nil, errors.New("missing id_token")
}
// Parse and verify ID Token payload.
idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil {
// handle error
}
// // Extract custom claims
// var claims struct {
// Email string `json:"email"`
// Verified bool `json:"email_verified"`
// }
// if err := idToken.Claims(&claims); err != nil {
// return nil, err
// }
return idToken, nil
}
}

View file

@ -25,8 +25,8 @@ type CreateProfileRequest struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
FlavorId string `protobuf:"bytes,1,opt,name=flavor_id,json=flavorId,proto3" json:"flavor_id,omitempty"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` FlavorId string `protobuf:"bytes,2,opt,name=flavor_id,json=flavorId,proto3" json:"flavor_id,omitempty"`
} }
func (x *CreateProfileRequest) Reset() { func (x *CreateProfileRequest) Reset() {
@ -59,16 +59,16 @@ func (*CreateProfileRequest) Descriptor() ([]byte, []int) {
return file_vpn_v1_vpn_proto_rawDescGZIP(), []int{0} return file_vpn_v1_vpn_proto_rawDescGZIP(), []int{0}
} }
func (x *CreateProfileRequest) GetFlavorId() string { func (x *CreateProfileRequest) GetName() string {
if x != nil { if x != nil {
return x.FlavorId return x.Name
} }
return "" return ""
} }
func (x *CreateProfileRequest) GetName() string { func (x *CreateProfileRequest) GetFlavorId() string {
if x != nil { if x != nil {
return x.Name return x.FlavorId
} }
return "" return ""
} }
@ -268,16 +268,166 @@ func (x *Flavor) GetDescription() string {
return "" return ""
} }
type ListProfilesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *ListProfilesRequest) Reset() {
*x = ListProfilesRequest{}
mi := &file_vpn_v1_vpn_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListProfilesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListProfilesRequest) ProtoMessage() {}
func (x *ListProfilesRequest) ProtoReflect() protoreflect.Message {
mi := &file_vpn_v1_vpn_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 ListProfilesRequest.ProtoReflect.Descriptor instead.
func (*ListProfilesRequest) Descriptor() ([]byte, []int) {
return file_vpn_v1_vpn_proto_rawDescGZIP(), []int{5}
}
type ListProfilesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Profiles []*Profile `protobuf:"bytes,1,rep,name=profiles,proto3" json:"profiles,omitempty"`
}
func (x *ListProfilesResponse) Reset() {
*x = ListProfilesResponse{}
mi := &file_vpn_v1_vpn_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListProfilesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListProfilesResponse) ProtoMessage() {}
func (x *ListProfilesResponse) ProtoReflect() protoreflect.Message {
mi := &file_vpn_v1_vpn_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 ListProfilesResponse.ProtoReflect.Descriptor instead.
func (*ListProfilesResponse) Descriptor() ([]byte, []int) {
return file_vpn_v1_vpn_proto_rawDescGZIP(), []int{6}
}
func (x *ListProfilesResponse) GetProfiles() []*Profile {
if x != nil {
return x.Profiles
}
return nil
}
type Profile struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
FlavorId string `protobuf:"bytes,3,opt,name=flavor_id,json=flavorId,proto3" json:"flavor_id,omitempty"`
ConnectionString string `protobuf:"bytes,4,opt,name=connection_string,json=connectionString,proto3" json:"connection_string,omitempty"`
}
func (x *Profile) Reset() {
*x = Profile{}
mi := &file_vpn_v1_vpn_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Profile) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Profile) ProtoMessage() {}
func (x *Profile) ProtoReflect() protoreflect.Message {
mi := &file_vpn_v1_vpn_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 Profile.ProtoReflect.Descriptor instead.
func (*Profile) Descriptor() ([]byte, []int) {
return file_vpn_v1_vpn_proto_rawDescGZIP(), []int{7}
}
func (x *Profile) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *Profile) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Profile) GetFlavorId() string {
if x != nil {
return x.FlavorId
}
return ""
}
func (x *Profile) GetConnectionString() string {
if x != nil {
return x.ConnectionString
}
return ""
}
var File_vpn_v1_vpn_proto protoreflect.FileDescriptor var File_vpn_v1_vpn_proto protoreflect.FileDescriptor
var file_vpn_v1_vpn_proto_rawDesc = []byte{ var file_vpn_v1_vpn_proto_rawDesc = []byte{
0x0a, 0x10, 0x76, 0x70, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x70, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x0a, 0x10, 0x76, 0x70, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x70, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x06, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x22, 0x47, 0x0a, 0x14, 0x43, 0x72, 0x74, 0x6f, 0x12, 0x06, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x22, 0x47, 0x0a, 0x14, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x61, 0x76, 0x6f, 0x72,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x6c, 0x61, 0x76, 0x6f,
0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x72, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f,
0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x11, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x11,
0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e,
@ -295,28 +445,46 @@ var file_vpn_v1_vpn_proto_rawDesc = []byte{
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xba, 0x01, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f,
0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x41, 0x76, 0x61, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x14,
0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x73, 0x12, 0x1f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x76, 0x61, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73,
0x46, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e,
0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x76, 0x61, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
0x65, 0x46, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x77, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02,
0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04,
0x69, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20,
0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x2b, 0x0a,
0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x69,
0x22, 0x00, 0x42, 0x91, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x31, 0x42, 0x08, 0x56, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x76, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x87, 0x02, 0x0a, 0x0f, 0x50,
0x70, 0x6e, 0x2e, 0x6b, 0x6f, 0x6e, 0x66, 0x61, 0x2e, 0x63, 0x68, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x57,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x0a, 0x10, 0x41, 0x76, 0x61, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x76, 0x6f,
0x65, 0x72, 0x79, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x73, 0x12, 0x1f, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x76, 0x61, 0x6c,
0x65, 0x6e, 0x2f, 0x76, 0x70, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x70, 0x6e, 0x76, 0x31, 0xa2, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75,
0x02, 0x03, 0x56, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x56, 0x70, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x76, 0x61,
0x06, 0x56, 0x70, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x56, 0x70, 0x6e, 0x5c, 0x56, 0x31, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73,
0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x56, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74,
0x70, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76,
0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50,
0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x76, 0x70, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x42, 0x91, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x70, 0x6e,
0x2e, 0x76, 0x31, 0x42, 0x08, 0x56, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
0x40, 0x76, 0x70, 0x6e, 0x2e, 0x6b, 0x6f, 0x6e, 0x66, 0x61, 0x2e, 0x63, 0x68, 0x2f, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x64, 0x65, 0x6c,
0x69, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x76, 0x70, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x70, 0x6e, 0x76,
0x31, 0xa2, 0x02, 0x03, 0x56, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x56, 0x70, 0x6e, 0x2e, 0x56, 0x31,
0xca, 0x02, 0x06, 0x56, 0x70, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x56, 0x70, 0x6e, 0x5c,
0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
0x07, 0x56, 0x70, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -331,25 +499,31 @@ func file_vpn_v1_vpn_proto_rawDescGZIP() []byte {
return file_vpn_v1_vpn_proto_rawDescData return file_vpn_v1_vpn_proto_rawDescData
} }
var file_vpn_v1_vpn_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_vpn_v1_vpn_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_vpn_v1_vpn_proto_goTypes = []any{ var file_vpn_v1_vpn_proto_goTypes = []any{
(*CreateProfileRequest)(nil), // 0: vpn.v1.CreateProfileRequest (*CreateProfileRequest)(nil), // 0: vpn.v1.CreateProfileRequest
(*CreateProfileResponse)(nil), // 1: vpn.v1.CreateProfileResponse (*CreateProfileResponse)(nil), // 1: vpn.v1.CreateProfileResponse
(*AvaliableFlavorsRequest)(nil), // 2: vpn.v1.AvaliableFlavorsRequest (*AvaliableFlavorsRequest)(nil), // 2: vpn.v1.AvaliableFlavorsRequest
(*AvaliableFlavorsResponse)(nil), // 3: vpn.v1.AvaliableFlavorsResponse (*AvaliableFlavorsResponse)(nil), // 3: vpn.v1.AvaliableFlavorsResponse
(*Flavor)(nil), // 4: vpn.v1.Flavor (*Flavor)(nil), // 4: vpn.v1.Flavor
(*ListProfilesRequest)(nil), // 5: vpn.v1.ListProfilesRequest
(*ListProfilesResponse)(nil), // 6: vpn.v1.ListProfilesResponse
(*Profile)(nil), // 7: vpn.v1.Profile
} }
var file_vpn_v1_vpn_proto_depIdxs = []int32{ var file_vpn_v1_vpn_proto_depIdxs = []int32{
4, // 0: vpn.v1.AvaliableFlavorsResponse.flavors:type_name -> vpn.v1.Flavor 4, // 0: vpn.v1.AvaliableFlavorsResponse.flavors:type_name -> vpn.v1.Flavor
2, // 1: vpn.v1.ProfilesService.AvaliableFlavors:input_type -> vpn.v1.AvaliableFlavorsRequest 7, // 1: vpn.v1.ListProfilesResponse.profiles:type_name -> vpn.v1.Profile
0, // 2: vpn.v1.ProfilesService.CreateProfile:input_type -> vpn.v1.CreateProfileRequest 2, // 2: vpn.v1.ProfilesService.AvaliableFlavors:input_type -> vpn.v1.AvaliableFlavorsRequest
3, // 3: vpn.v1.ProfilesService.AvaliableFlavors:output_type -> vpn.v1.AvaliableFlavorsResponse 0, // 3: vpn.v1.ProfilesService.CreateProfile:input_type -> vpn.v1.CreateProfileRequest
1, // 4: vpn.v1.ProfilesService.CreateProfile:output_type -> vpn.v1.CreateProfileResponse 5, // 4: vpn.v1.ProfilesService.ListProfiles:input_type -> vpn.v1.ListProfilesRequest
3, // [3:5] is the sub-list for method output_type 3, // 5: vpn.v1.ProfilesService.AvaliableFlavors:output_type -> vpn.v1.AvaliableFlavorsResponse
1, // [1:3] is the sub-list for method input_type 1, // 6: vpn.v1.ProfilesService.CreateProfile:output_type -> vpn.v1.CreateProfileResponse
1, // [1:1] is the sub-list for extension type_name 6, // 7: vpn.v1.ProfilesService.ListProfiles:output_type -> vpn.v1.ListProfilesResponse
1, // [1:1] is the sub-list for extension extendee 5, // [5:8] is the sub-list for method output_type
0, // [0:1] is the sub-list for field type_name 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_vpn_v1_vpn_proto_init() } func init() { file_vpn_v1_vpn_proto_init() }
@ -364,7 +538,7 @@ func file_vpn_v1_vpn_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_vpn_v1_vpn_proto_rawDesc, RawDescriptor: file_vpn_v1_vpn_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 5, NumMessages: 8,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View file

@ -39,6 +39,9 @@ const (
// ProfilesServiceCreateProfileProcedure is the fully-qualified name of the ProfilesService's // ProfilesServiceCreateProfileProcedure is the fully-qualified name of the ProfilesService's
// CreateProfile RPC. // CreateProfile RPC.
ProfilesServiceCreateProfileProcedure = "/vpn.v1.ProfilesService/CreateProfile" ProfilesServiceCreateProfileProcedure = "/vpn.v1.ProfilesService/CreateProfile"
// ProfilesServiceListProfilesProcedure is the fully-qualified name of the ProfilesService's
// ListProfiles RPC.
ProfilesServiceListProfilesProcedure = "/vpn.v1.ProfilesService/ListProfiles"
) )
// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package.
@ -46,12 +49,14 @@ var (
profilesServiceServiceDescriptor = v1.File_vpn_v1_vpn_proto.Services().ByName("ProfilesService") profilesServiceServiceDescriptor = v1.File_vpn_v1_vpn_proto.Services().ByName("ProfilesService")
profilesServiceAvaliableFlavorsMethodDescriptor = profilesServiceServiceDescriptor.Methods().ByName("AvaliableFlavors") profilesServiceAvaliableFlavorsMethodDescriptor = profilesServiceServiceDescriptor.Methods().ByName("AvaliableFlavors")
profilesServiceCreateProfileMethodDescriptor = profilesServiceServiceDescriptor.Methods().ByName("CreateProfile") profilesServiceCreateProfileMethodDescriptor = profilesServiceServiceDescriptor.Methods().ByName("CreateProfile")
profilesServiceListProfilesMethodDescriptor = profilesServiceServiceDescriptor.Methods().ByName("ListProfiles")
) )
// ProfilesServiceClient is a client for the vpn.v1.ProfilesService service. // ProfilesServiceClient is a client for the vpn.v1.ProfilesService service.
type ProfilesServiceClient interface { type ProfilesServiceClient interface {
AvaliableFlavors(context.Context, *connect.Request[v1.AvaliableFlavorsRequest]) (*connect.Response[v1.AvaliableFlavorsResponse], error) AvaliableFlavors(context.Context, *connect.Request[v1.AvaliableFlavorsRequest]) (*connect.Response[v1.AvaliableFlavorsResponse], error)
CreateProfile(context.Context, *connect.Request[v1.CreateProfileRequest]) (*connect.Response[v1.CreateProfileResponse], error) CreateProfile(context.Context, *connect.Request[v1.CreateProfileRequest]) (*connect.Response[v1.CreateProfileResponse], error)
ListProfiles(context.Context, *connect.Request[v1.ListProfilesRequest]) (*connect.Response[v1.ListProfilesResponse], error)
} }
// NewProfilesServiceClient constructs a client for the vpn.v1.ProfilesService service. By default, // NewProfilesServiceClient constructs a client for the vpn.v1.ProfilesService service. By default,
@ -76,6 +81,12 @@ func NewProfilesServiceClient(httpClient connect.HTTPClient, baseURL string, opt
connect.WithSchema(profilesServiceCreateProfileMethodDescriptor), connect.WithSchema(profilesServiceCreateProfileMethodDescriptor),
connect.WithClientOptions(opts...), connect.WithClientOptions(opts...),
), ),
listProfiles: connect.NewClient[v1.ListProfilesRequest, v1.ListProfilesResponse](
httpClient,
baseURL+ProfilesServiceListProfilesProcedure,
connect.WithSchema(profilesServiceListProfilesMethodDescriptor),
connect.WithClientOptions(opts...),
),
} }
} }
@ -83,6 +94,7 @@ func NewProfilesServiceClient(httpClient connect.HTTPClient, baseURL string, opt
type profilesServiceClient struct { type profilesServiceClient struct {
avaliableFlavors *connect.Client[v1.AvaliableFlavorsRequest, v1.AvaliableFlavorsResponse] avaliableFlavors *connect.Client[v1.AvaliableFlavorsRequest, v1.AvaliableFlavorsResponse]
createProfile *connect.Client[v1.CreateProfileRequest, v1.CreateProfileResponse] createProfile *connect.Client[v1.CreateProfileRequest, v1.CreateProfileResponse]
listProfiles *connect.Client[v1.ListProfilesRequest, v1.ListProfilesResponse]
} }
// AvaliableFlavors calls vpn.v1.ProfilesService.AvaliableFlavors. // AvaliableFlavors calls vpn.v1.ProfilesService.AvaliableFlavors.
@ -95,10 +107,16 @@ func (c *profilesServiceClient) CreateProfile(ctx context.Context, req *connect.
return c.createProfile.CallUnary(ctx, req) return c.createProfile.CallUnary(ctx, req)
} }
// ListProfiles calls vpn.v1.ProfilesService.ListProfiles.
func (c *profilesServiceClient) ListProfiles(ctx context.Context, req *connect.Request[v1.ListProfilesRequest]) (*connect.Response[v1.ListProfilesResponse], error) {
return c.listProfiles.CallUnary(ctx, req)
}
// ProfilesServiceHandler is an implementation of the vpn.v1.ProfilesService service. // ProfilesServiceHandler is an implementation of the vpn.v1.ProfilesService service.
type ProfilesServiceHandler interface { type ProfilesServiceHandler interface {
AvaliableFlavors(context.Context, *connect.Request[v1.AvaliableFlavorsRequest]) (*connect.Response[v1.AvaliableFlavorsResponse], error) AvaliableFlavors(context.Context, *connect.Request[v1.AvaliableFlavorsRequest]) (*connect.Response[v1.AvaliableFlavorsResponse], error)
CreateProfile(context.Context, *connect.Request[v1.CreateProfileRequest]) (*connect.Response[v1.CreateProfileResponse], error) CreateProfile(context.Context, *connect.Request[v1.CreateProfileRequest]) (*connect.Response[v1.CreateProfileResponse], error)
ListProfiles(context.Context, *connect.Request[v1.ListProfilesRequest]) (*connect.Response[v1.ListProfilesResponse], error)
} }
// NewProfilesServiceHandler builds an HTTP handler from the service implementation. It returns the // NewProfilesServiceHandler builds an HTTP handler from the service implementation. It returns the
@ -119,12 +137,20 @@ func NewProfilesServiceHandler(svc ProfilesServiceHandler, opts ...connect.Handl
connect.WithSchema(profilesServiceCreateProfileMethodDescriptor), connect.WithSchema(profilesServiceCreateProfileMethodDescriptor),
connect.WithHandlerOptions(opts...), connect.WithHandlerOptions(opts...),
) )
profilesServiceListProfilesHandler := connect.NewUnaryHandler(
ProfilesServiceListProfilesProcedure,
svc.ListProfiles,
connect.WithSchema(profilesServiceListProfilesMethodDescriptor),
connect.WithHandlerOptions(opts...),
)
return "/vpn.v1.ProfilesService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return "/vpn.v1.ProfilesService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path { switch r.URL.Path {
case ProfilesServiceAvaliableFlavorsProcedure: case ProfilesServiceAvaliableFlavorsProcedure:
profilesServiceAvaliableFlavorsHandler.ServeHTTP(w, r) profilesServiceAvaliableFlavorsHandler.ServeHTTP(w, r)
case ProfilesServiceCreateProfileProcedure: case ProfilesServiceCreateProfileProcedure:
profilesServiceCreateProfileHandler.ServeHTTP(w, r) profilesServiceCreateProfileHandler.ServeHTTP(w, r)
case ProfilesServiceListProfilesProcedure:
profilesServiceListProfilesHandler.ServeHTTP(w, r)
default: default:
http.NotFound(w, r) http.NotFound(w, r)
} }
@ -141,3 +167,7 @@ func (UnimplementedProfilesServiceHandler) AvaliableFlavors(context.Context, *co
func (UnimplementedProfilesServiceHandler) CreateProfile(context.Context, *connect.Request[v1.CreateProfileRequest]) (*connect.Response[v1.CreateProfileResponse], error) { func (UnimplementedProfilesServiceHandler) CreateProfile(context.Context, *connect.Request[v1.CreateProfileRequest]) (*connect.Response[v1.CreateProfileResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vpn.v1.ProfilesService.CreateProfile is not implemented")) return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vpn.v1.ProfilesService.CreateProfile is not implemented"))
} }
func (UnimplementedProfilesServiceHandler) ListProfiles(context.Context, *connect.Request[v1.ListProfilesRequest]) (*connect.Response[v1.ListProfilesResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vpn.v1.ProfilesService.ListProfiles is not implemented"))
}

View file

@ -8,7 +8,7 @@ import (
"vpn.konfa.ch/controller/src/delivery/grpcserver/gen/vpn/v1/vpnv1connect" "vpn.konfa.ch/controller/src/delivery/grpcserver/gen/vpn/v1/vpnv1connect"
) )
func NewVPNService() *ProfilesService { func NewProfileService() *ProfilesService {
return &ProfilesService{} return &ProfilesService{}
} }
@ -16,6 +16,11 @@ type ProfilesService struct {
// vpnv1connect.UnimplementedVPNServiceHandler // vpnv1connect.UnimplementedVPNServiceHandler
} }
// ListProfiles implements vpnv1connect.ProfilesServiceHandler.
func (v *ProfilesService) ListProfiles(context.Context, *connect.Request[vpnv1.ListProfilesRequest]) (*connect.Response[vpnv1.ListProfilesResponse], error) {
panic("unimplemented")
}
// CreateProfile implements vpnv1connect.VPNServiceHandler. // CreateProfile implements vpnv1connect.VPNServiceHandler.
func (v *ProfilesService) CreateProfile(ctx context.Context, req *connect.Request[vpnv1.CreateProfileRequest]) (*connect.Response[vpnv1.CreateProfileResponse], error) { func (v *ProfilesService) CreateProfile(ctx context.Context, req *connect.Request[vpnv1.CreateProfileRequest]) (*connect.Response[vpnv1.CreateProfileResponse], error) {
panic("unimplemented") panic("unimplemented")
@ -23,7 +28,13 @@ func (v *ProfilesService) CreateProfile(ctx context.Context, req *connect.Reques
// AvaliableFlavors implements vpnv1connect.ProfilesServiceHandler. // AvaliableFlavors implements vpnv1connect.ProfilesServiceHandler.
func (v *ProfilesService) AvaliableFlavors(ctx context.Context, req *connect.Request[vpnv1.AvaliableFlavorsRequest]) (*connect.Response[vpnv1.AvaliableFlavorsResponse], error) { func (v *ProfilesService) AvaliableFlavors(ctx context.Context, req *connect.Request[vpnv1.AvaliableFlavorsRequest]) (*connect.Response[vpnv1.AvaliableFlavorsResponse], error) {
return &connect.Response[vpnv1.AvaliableFlavorsResponse]{}, nil return connect.NewResponse(&vpnv1.AvaliableFlavorsResponse{
Flavors: []*vpnv1.Flavor{
{
Name: "vless",
},
},
}), nil
} }
var _ vpnv1connect.ProfilesServiceHandler = (*ProfilesService)(nil) var _ vpnv1connect.ProfilesServiceHandler = (*ProfilesService)(nil)

View file

@ -0,0 +1,35 @@
package grpcserver
import (
"context"
"net/http"
"connectrpc.com/authn"
"github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"vpn.konfa.ch/controller/src/config"
"vpn.konfa.ch/controller/src/delivery/grpcserver/gen/vpn/v1/vpnv1connect"
)
func Run(ctx context.Context, addr string, oidcConfig config.OIDC) error {
oidcProvider, err := oidc.NewProvider(ctx, oidcConfig.Issuer)
if err != nil {
return err
}
mux := http.NewServeMux()
profileService := NewProfileService()
mux.Handle(vpnv1connect.NewProfilesServiceHandler(profileService))
handler := authn.NewMiddleware(
oidcAuth(oidcProvider, oidcConfig.ClientID, oidcConfig.ClientSecret, oidcConfig.RedirectURL),
).Wrap(mux)
return http.ListenAndServe(
addr,
// For gRPC clients, it's convenient to support HTTP/2 without TLS. You can
// avoid x/net/http2 by using http.ListenAndServeTLS.
h2c.NewHandler(handler, &http2.Server{}),
)
}