Add basic way to get backend from query (#48)
Because polyculeconnect is a OIDC proxy, we need to know which auth backend to use. This is provided using a query param or a form, so we need to get it from our own middleware. This commit adds the following elements: - basic DB storage for the backends - support for DB migrations and a first test migration (not definitive) - middleware to get the backend from the request and put it in the context - test that the backend exists in the auth flow
This commit is contained in:
parent
f3060bee3b
commit
64e48a5689
12 changed files with 268 additions and 54 deletions
60
polyculeconnect/cmd/db/migrate.go
Normal file
60
polyculeconnect/cmd/db/migrate.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/cmd/utils"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/config"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/internal/db"
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
"github.com/golang-migrate/migrate/v4/database/sqlite3"
|
||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// migrateCmd represents the db migrate command
|
||||
var migrateCmd = &cobra.Command{
|
||||
Use: "migrate",
|
||||
Short: "Run the database migrations",
|
||||
Long: `Run the database migrations.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
conf := utils.InitConfig("")
|
||||
if err := runMigrations(conf); err != nil {
|
||||
utils.Failf("Failed to run migrations: %s", err.Error())
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func runMigrations(conf *config.AppConfig) error {
|
||||
storage, err := db.New(*conf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to db: %w", err)
|
||||
}
|
||||
driver, err := sqlite3.WithInstance(storage.DB(), &sqlite3.Config{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open sqlite3 driver: %w", err)
|
||||
}
|
||||
|
||||
m, err := migrate.NewWithDatabaseInstance("file://migrations", "", driver)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to init migrator: %w", err)
|
||||
}
|
||||
if err := m.Up(); err != nil {
|
||||
return fmt.Errorf("failed to run migrations: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
dbCmd.AddCommand(migrateCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// dbCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// dbCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
|
@ -10,6 +10,7 @@ import (
|
|||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/cmd"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/cmd/utils"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/internal/db"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/internal/middlewares"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/internal/storage"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/logger"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/server"
|
||||
|
@ -68,6 +69,7 @@ func serve() {
|
|||
options := []op.Option{
|
||||
op.WithAllowInsecure(),
|
||||
op.WithLogger(slogger),
|
||||
op.WithHttpInterceptors(middlewares.WithBackendFromRequestMiddleware),
|
||||
}
|
||||
provider, err := op.NewProvider(&opConf, &st, op.StaticIssuer(conf.Issuer), options...)
|
||||
if err != nil {
|
||||
|
|
|
@ -7,11 +7,13 @@ toolchain go1.22.6
|
|||
require (
|
||||
github.com/dexidp/dex v0.0.0-20231014000322-089f374d4f3e
|
||||
github.com/go-jose/go-jose/v4 v4.0.4
|
||||
github.com/golang-migrate/migrate/v4 v4.17.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/mattn/go-sqlite3 v1.14.17
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/zitadel/oidc v1.13.5
|
||||
github.com/zitadel/oidc/v3 v3.27.0
|
||||
go.uber.org/zap v1.24.0
|
||||
go.uber.org/zap/exp v0.2.0
|
||||
|
@ -42,20 +44,19 @@ require (
|
|||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/gorilla/handlers v1.5.1 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gorilla/schema v1.2.0 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/huandu/xstrings v1.3.3 // indirect
|
||||
github.com/imdario/mergo v0.3.11 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
||||
|
@ -81,15 +82,15 @@ require (
|
|||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 // indirect
|
||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/oauth2 v0.22.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
google.golang.org/api v0.147.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect
|
||||
google.golang.org/grpc v1.58.3 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
google.golang.org/api v0.150.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
@ -65,6 +65,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-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4=
|
||||
github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
|
@ -102,18 +104,21 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
||||
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
||||
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
||||
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
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-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
|
||||
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
|
@ -205,8 +210,6 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
|
|||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank=
|
||||
github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow=
|
||||
github.com/zitadel/oidc v1.13.5 h1:7jhh68NGZitLqwLiVU9Dtwa4IraJPFF1vS+4UupO93U=
|
||||
github.com/zitadel/oidc v1.13.5/go.mod h1:rHs1DhU3Sv3tnI6bQRVlFa3u0lCwtR7S21WHY+yXgPA=
|
||||
github.com/zitadel/oidc/v3 v3.27.0 h1:zeYpyRH0UcgdCjVHUYzSsqf1jbSwVMPVxYKOnRXstgU=
|
||||
github.com/zitadel/oidc/v3 v3.27.0/go.mod h1:ZwBEqSviCpJVZiYashzo53bEGRGXi7amE5Q8PpQg9IM=
|
||||
github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0=
|
||||
|
@ -238,8 +241,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
|||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 h1:fGZugkZk2UgYBxtpKmvub51Yno1LJDeEsRp2xGD+0gY=
|
||||
golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
|
||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
|
@ -310,26 +313,26 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
|
|||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.147.0 h1:Can3FaQo9LlVqxJCodNmeZW/ib3/qKAY3rFeXiHo5gc=
|
||||
google.golang.org/api v0.147.0/go.mod h1:pQ/9j83DcmPd/5C9e2nFOdjjNkDZ1G+zkbK2uvdkJMs=
|
||||
google.golang.org/api v0.150.0 h1:Z9k22qD289SZ8gCJrk4DrWXkNjtfvKAUo/l1ma8eBYE=
|
||||
google.golang.org/api v0.150.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0=
|
||||
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c h1:jHkCUWkseRf+W+edG5hMzr/Uh1xkDREY4caybAq4dpY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
|
||||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA=
|
||||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
|
||||
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -341,8 +344,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
|||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
|
46
polyculeconnect/internal/db/backend/backend.go
Normal file
46
polyculeconnect/internal/db/backend/backend.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/internal/model"
|
||||
)
|
||||
|
||||
var ErrNotFound = errors.New("backend not found")
|
||||
|
||||
// const backendRows = `"id", "name", "oidc_id", "oidc_secret"`
|
||||
const backendRows = `"id", "name"`
|
||||
|
||||
type BackendDB interface {
|
||||
GetBackendByName(ctx context.Context, name string) (*model.Backend, error)
|
||||
}
|
||||
|
||||
type sqlBackendDB struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func backendFromRow(row sql.Row) (*model.Backend, error) {
|
||||
var res model.Backend
|
||||
|
||||
if err := row.Scan(&res.ID, &res.Name); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return nil, fmt.Errorf("invalid format for backend: %w", err)
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (db *sqlBackendDB) GetBackendByName(ctx context.Context, name string) (*model.Backend, error) {
|
||||
query := fmt.Sprintf(`SELECT %s FROM "backend" WHERE "name" = ?`, backendRows)
|
||||
fmt.Println(query, name)
|
||||
row := db.db.QueryRowContext(ctx, query, name)
|
||||
return backendFromRow(*row)
|
||||
}
|
||||
|
||||
func New(db *sql.DB) *sqlBackendDB {
|
||||
return &sqlBackendDB{db: db}
|
||||
}
|
|
@ -1,5 +1,40 @@
|
|||
package db
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
var ErrNotFound = errors.New("not found")
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/config"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/internal/db/backend"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/internal/db/client"
|
||||
)
|
||||
|
||||
type Storage interface {
|
||||
DB() *sql.DB
|
||||
ClientStorage() client.ClientDB
|
||||
BackendStorage() backend.BackendDB
|
||||
}
|
||||
|
||||
type sqlStorage struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (s *sqlStorage) DB() *sql.DB {
|
||||
return s.db
|
||||
}
|
||||
|
||||
func (s *sqlStorage) ClientStorage() client.ClientDB {
|
||||
return client.New(s.db)
|
||||
}
|
||||
|
||||
func (s *sqlStorage) BackendStorage() backend.BackendDB {
|
||||
return backend.New(s.db)
|
||||
}
|
||||
|
||||
func New(conf config.AppConfig) (Storage, error) {
|
||||
db, err := sql.Open("sqlite3", conf.StorageConfig.File)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open DB: %w", err)
|
||||
}
|
||||
return &sqlStorage{db: db}, nil
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package db
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/config"
|
||||
"git.faercol.me/faercol/polyculeconnect/polyculeconnect/internal/model"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
var ErrNotFound = errors.New("not found")
|
||||
|
||||
const clientRows = `"client"."id", "client"."secret", "client"."redirect_uris", "client"."trusted_peers", "client"."name"`
|
||||
|
||||
type ClientDB interface {
|
||||
|
@ -22,18 +23,12 @@ type sqlClientDB struct {
|
|||
db *sql.DB
|
||||
}
|
||||
|
||||
func strArrayToSlice(rawVal string) []string { // TODO this won't work if there's more than one element
|
||||
res := []string{}
|
||||
insideStr, ok := strings.CutPrefix(rawVal, `["`)
|
||||
if !ok {
|
||||
return res
|
||||
func strArrayToSlice(rawVal string) []string {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(rawVal), &res); err != nil {
|
||||
return nil
|
||||
}
|
||||
insideStr, ok = strings.CutSuffix(insideStr, `"]`)
|
||||
if !ok {
|
||||
return res
|
||||
}
|
||||
|
||||
return []string{insideStr}
|
||||
return res
|
||||
}
|
||||
|
||||
func clientFromRow(row *sql.Row) (*model.Client, error) {
|
||||
|
@ -60,10 +55,6 @@ func (db *sqlClientDB) GetClientByID(ctx context.Context, id string) (*model.Cli
|
|||
return clientFromRow(row)
|
||||
}
|
||||
|
||||
func New(conf config.AppConfig) (*sqlClientDB, error) {
|
||||
db, err := sql.Open("sqlite3", conf.StorageConfig.File)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open DB: %w", err)
|
||||
}
|
||||
return &sqlClientDB{db: db}, nil
|
||||
func New(db *sql.DB) *sqlClientDB {
|
||||
return &sqlClientDB{db: db}
|
||||
}
|
40
polyculeconnect/internal/middlewares/test.go
Normal file
40
polyculeconnect/internal/middlewares/test.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package middlewares
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
backendNameQueryParam = "connector_id"
|
||||
backendCtxKeyName = "backendName"
|
||||
)
|
||||
|
||||
type BackendFromRequestMiddleware struct {
|
||||
h http.Handler
|
||||
}
|
||||
|
||||
func (m *BackendFromRequestMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
// TODO: handle this better
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
backendName := r.Form.Get(backendNameQueryParam)
|
||||
// TODO this should be explicitly handled
|
||||
if backendName == "" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("no backend id provided"))
|
||||
return
|
||||
}
|
||||
|
||||
// TODO we should test that this backend actually exists here
|
||||
|
||||
ctx := context.WithValue(r.Context(), backendCtxKeyName, backendName)
|
||||
m.h.ServeHTTP(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
func WithBackendFromRequestMiddleware(input http.Handler) http.Handler {
|
||||
return &BackendFromRequestMiddleware{h: input}
|
||||
}
|
10
polyculeconnect/internal/model/backend.go
Normal file
10
polyculeconnect/internal/model/backend.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package model
|
||||
|
||||
import "github.com/google/uuid"
|
||||
|
||||
type Backend struct {
|
||||
ID uuid.UUID
|
||||
Name string
|
||||
OIDCID string
|
||||
OIDCSecret string
|
||||
}
|
|
@ -2,6 +2,7 @@ package storage
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -17,13 +18,23 @@ func ErrNotImplemented(name string) error {
|
|||
|
||||
// Storage implements the Storage interface from zitadel/oidc/op
|
||||
type Storage struct {
|
||||
LocalStorage db.ClientDB
|
||||
LocalStorage db.Storage
|
||||
}
|
||||
|
||||
/*
|
||||
Auth storage interface
|
||||
*/
|
||||
func (s *Storage) CreateAuthRequest(ctx context.Context, req *oidc.AuthRequest, userID string) (op.AuthRequest, error) {
|
||||
// validate that the connector is correct
|
||||
backendName, ok := stringFromCtx(ctx, "backendName")
|
||||
if !ok {
|
||||
return nil, errors.New("no backend name provided")
|
||||
}
|
||||
_, err := s.LocalStorage.BackendStorage().GetBackendByName(ctx, backendName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get backend: %w", err)
|
||||
}
|
||||
|
||||
return nil, ErrNotImplemented("CreateAuthRequest")
|
||||
}
|
||||
|
||||
|
@ -84,7 +95,7 @@ func (s *Storage) KeySet(ctx context.Context) ([]op.Key, error) {
|
|||
*/
|
||||
|
||||
func (s *Storage) GetClientByClientID(ctx context.Context, clientID string) (op.Client, error) {
|
||||
clt, err := s.LocalStorage.GetClientByID(ctx, clientID)
|
||||
clt, err := s.LocalStorage.ClientStorage().GetClientByID(ctx, clientID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get client from local storage: %w", err)
|
||||
}
|
||||
|
@ -123,3 +134,13 @@ func (s *Storage) ValidateJWTProfileScopes(ctx context.Context, userID string, s
|
|||
func (s *Storage) Health(ctx context.Context) error {
|
||||
return ErrNotImplemented("Health")
|
||||
}
|
||||
|
||||
func stringFromCtx(ctx context.Context, key string) (string, bool) {
|
||||
rawVal := ctx.Value(key)
|
||||
if rawVal == nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
val, ok := rawVal.(string)
|
||||
return val, ok
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE "backend";
|
4
polyculeconnect/migrations/0_create_backend_table.up.sql
Normal file
4
polyculeconnect/migrations/0_create_backend_table.up.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
CREATE TABLE "backend" (
|
||||
id TEXT NOT NULL PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE
|
||||
);
|
Loading…
Reference in a new issue