diff --git a/go.mod b/go.mod index f6566a64..017cdd2a 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( github.com/theopenlane/echozap v0.1.0 github.com/theopenlane/entx v0.1.4 github.com/theopenlane/gqlgen-plugins v0.1.0 - github.com/theopenlane/httpsling v0.1.0 + github.com/theopenlane/httpsling v0.2.0 github.com/theopenlane/iam v0.1.6 github.com/theopenlane/utils v0.1.5 github.com/tursodatabase/libsql-client-go v0.0.0-20240902231107-85af5b9d094d @@ -118,7 +118,6 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-faster/errors v0.7.1 // indirect github.com/go-faster/jx v1.1.0 // indirect @@ -128,12 +127,10 @@ require ( github.com/go-openapi/inflect v0.21.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/x v0.1.14 // indirect github.com/goccy/go-json v0.10.3 // indirect - github.com/goccy/go-yaml v1.12.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect @@ -245,7 +242,6 @@ require ( go.opentelemetry.io/otel/trace v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/arch v0.9.0 // indirect golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect diff --git a/go.sum b/go.sum index 083cf6a6..dd12a658 100644 --- a/go.sum +++ b/go.sum @@ -77,10 +77,6 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg= -github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -98,10 +94,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= @@ -160,8 +152,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= -github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlLgiA= github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk= github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= @@ -185,12 +175,6 @@ github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1 github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -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.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= -github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-redis/redismock/v8 v8.0.6 h1:rtuijPgGynsRB2Y7KDACm09WvjHWS4RaG44Nm7rcj4Y= @@ -207,8 +191,6 @@ github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 h1:FWNFq4fM1wPfcK40 github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= 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/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= -github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -323,8 +305,6 @@ github.com/karlseguin/ccache/v3 v3.0.5 h1:hFX25+fxzNjsRlREYsoGNa2LoVEw5mPF8wkWq/ github.com/karlseguin/ccache/v3 v3.0.5/go.mod h1:qxC372+Qn+IBj8Pe3KvGjHPj0sWwEF7AeZVhsNPZ6uY= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= -github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= 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/parsers/yaml v0.1.0 h1:ZZ8/iGfRLvKSaMEECEBPM1HQslrZADk8fP1XFUxVI5w= @@ -345,8 +325,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -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/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= @@ -546,16 +524,14 @@ github.com/theopenlane/entx v0.1.4 h1:dxP/+LUdMXBhbMoFq3ITkJv6vINxii1306BSrxHckn github.com/theopenlane/entx v0.1.4/go.mod h1:MxnlrB6Eid2BDwB5kKz7p9QP/Bm0/kpbr8z76CQvjw4= github.com/theopenlane/gqlgen-plugins v0.1.0 h1:DL3knGQ+pcoXceSFvmgWzzlgIyPRgl71tYPTySP+vHk= github.com/theopenlane/gqlgen-plugins v0.1.0/go.mod h1:sP0nCjrE3KoVT4qfYqMrSK1XZa3Bx2oTIRSdEF7F5l0= -github.com/theopenlane/httpsling v0.1.0 h1:IHWUSo213stJTmHOHjNIg5b3npgpchzMdPMY7jAkimI= -github.com/theopenlane/httpsling v0.1.0/go.mod h1:wOyNfO4moIbmP4stQc9Kasgp+Q4sODo3LOLwvjUe/PA= +github.com/theopenlane/httpsling v0.2.0 h1:5k/PoFA5jjak9dnijATFvTVTvgUSMFdEZeyctyv1cWU= +github.com/theopenlane/httpsling v0.2.0/go.mod h1:Ta/8bjv4JhKT0Xk1hD2Iott9BKLCqXvscmjolSB/bBY= github.com/theopenlane/iam v0.1.6 h1:ps6xLXHpnGy687uLPRZiD7034DRVqaWEfJLCJVMx95o= github.com/theopenlane/iam v0.1.6/go.mod h1:mOtYjuqUD7SX4EkwXFAYwf8+mwPDsRvTsLhAngqVIxM= github.com/theopenlane/utils v0.1.5 h1:4DRieQmsBF87n4lPjEkTt6s4iVRQaCGYlk2+C05lt3o= github.com/theopenlane/utils v0.1.5/go.mod h1:LWJzG9FfklsLlqWx/VdmfBMuNk700cWqHAwQL0299FM= github.com/tursodatabase/libsql-client-go v0.0.0-20240902231107-85af5b9d094d h1:dOMI4+zEbDI37KGb0TI44GUAwxHF9cMsIoDTJ7UmgfU= github.com/tursodatabase/libsql-client-go v0.0.0-20240902231107-85af5b9d094d/go.mod h1:l8xTsYB90uaVdMHXMCxKKLSgw5wLYBwBKKefNIUnm9s= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= @@ -623,8 +599,6 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= gocloud.dev v0.39.0 h1:EYABYGhAalPUaMrbSKOr5lejxoxvXj99nE8XFtsDgds= gocloud.dev v0.39.0/go.mod h1:drz+VyYNBvrMTW0KZiBAYEdl8lbNZx+OQ7oQvdrFmSQ= -golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k= -golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= diff --git a/internal/httpserve/authmanager/authmanager.go b/internal/httpserve/authmanager/authmanager.go index f069c8de..a6c7e837 100644 --- a/internal/httpserve/authmanager/authmanager.go +++ b/internal/httpserve/authmanager/authmanager.go @@ -8,7 +8,6 @@ import ( "github.com/golang-jwt/jwt/v5" echo "github.com/theopenlane/echox" - "github.com/theopenlane/httpsling" "github.com/theopenlane/iam/sessions" "github.com/theopenlane/iam/tokens" @@ -16,6 +15,10 @@ import ( "github.com/theopenlane/core/pkg/models" ) +const ( + bearerAuthType = "Bearer" +) + type Config struct { tokenManager *tokens.TokenManager sessionConfig *sessions.SessionConfig @@ -85,7 +88,7 @@ func (a *Config) GenerateUserAuthSessionWithOrg(ctx echo.Context, user *generate return nil, err } - auth.TokenType = string(httpsling.BearerAuthType) + auth.TokenType = bearerAuthType return auth, nil } @@ -102,7 +105,7 @@ func (a *Config) GenerateOauthAuthSession(ctx context.Context, w http.ResponseWr return nil, err } - auth.TokenType = string(httpsling.BearerAuthType) + auth.TokenType = bearerAuthType return auth, nil } diff --git a/pkg/openlaneclient/client.go b/pkg/openlaneclient/client.go index b2ded958..1c4d2970 100644 --- a/pkg/openlaneclient/client.go +++ b/pkg/openlaneclient/client.go @@ -52,7 +52,7 @@ func New(config Config, opts ...ClientOption) (*OpenlaneClient, error) { // create the graph client // use api.Config instead of config because some fields are updated in NewRestClient graphClient := NewClient( - api.HTTPSlingClient.HTTPClient, + api.Requester.HTTPClient(), graphRequestPath(api.Config), &api.Config.Clientv2Options, api.Config.Interceptors..., @@ -64,33 +64,12 @@ func New(config Config, opts ...ClientOption) (*OpenlaneClient, error) { }, nil } -// newHTTPClient creates a new HTTP sling client with the given configuration -func newHTTPClient(config Config) (*httpsling.Client, error) { - // copy the values from the base config to the httpsling config - if config.HTTPSling == nil { - config.HTTPSling = &httpsling.Config{} - } - - if config.HTTPSling.BaseURL == "" { - config.HTTPSling.BaseURL = config.BaseURL.String() - } - - client := httpsling.Create(config.HTTPSling) - - // set the default cookie jar - if err := client.SetDefaultCookieJar(); err != nil { - return nil, err - } - - return client, nil -} - // APIv1 implements the Client interface and provides methods to interact with the API type APIv1 struct { // Config is the configuration for the APIv1 client Config Config - // HTTPSlingClient is the HTTP client for the APIv1 client - HTTPSlingClient *httpsling.Client + // Requester is the HTTP client for the APIv1 client + Requester *httpsling.Requester } // Config is the configuration for the APIv1 client @@ -100,11 +79,11 @@ func (c *OpenlaneClient) Config() Config { return api.Config } -// HTTPSlingClient is the http client for the APIv1 client -func (c *OpenlaneClient) HTTPSlingClient() *httpsling.Client { +// HTTPSlingRequester is the http client for the APIv1 client +func (c *OpenlaneClient) HTTPSlingRequester() *httpsling.Requester { api := c.OpenlaneRestClient.(*APIv1) - return api.HTTPSlingClient + return api.Requester } // AccessToken returns the access token cached on the client or an error if it is not @@ -148,7 +127,7 @@ func (c *OpenlaneClient) RefreshToken() (_ string, err error) { // SetAuthTokens is a helper function to set the access and refresh tokens on the // client cookie jar. func (c *OpenlaneClient) SetAuthTokens(access, refresh string) error { - if c.HTTPSlingClient().HTTPClient.Jar == nil { + if c.HTTPSlingRequester().CookieJar() == nil { return ErrNoCookieJarSet } @@ -176,7 +155,7 @@ func (c *OpenlaneClient) SetAuthTokens(access, refresh string) error { }) } - c.Config().HTTPSling.CookieJar.SetCookies(u, cookies) + c.HTTPSlingRequester().CookieJar().SetCookies(u, cookies) return nil } @@ -198,11 +177,11 @@ func (c *OpenlaneClient) ClearAuthTokens() { // Returns the cookies set from the previous request(s) on the client Jar. func (c *OpenlaneClient) Cookies() ([]*http.Cookie, error) { - if c.HTTPSlingClient().HTTPClient.Jar == nil { + if c.HTTPSlingRequester().CookieJar() == nil { return nil, ErrNoCookieJarSet } - cookies := c.HTTPSlingClient().HTTPClient.Jar.Cookies(c.Config().BaseURL) + cookies := c.HTTPSlingRequester().CookieJar().Cookies(c.Config().BaseURL) return cookies, nil } diff --git a/pkg/openlaneclient/config.go b/pkg/openlaneclient/config.go index 8b97ce9e..e7850e7a 100644 --- a/pkg/openlaneclient/config.go +++ b/pkg/openlaneclient/config.go @@ -1,12 +1,9 @@ package openlaneclient import ( - "net/http" "net/url" "github.com/Yamashou/gqlgenc/clientv2" - - "github.com/theopenlane/httpsling" ) // Config is the configuration for the API client @@ -15,8 +12,6 @@ type Config struct { BaseURL *url.URL `json:"baseUrl" yaml:"base_url" default:"http://localhost:17608"` // GraphQLPath is the path to the GraphQL endpoint GraphQLPath string `json:"graphqlPath" default:"/query"` - // HTTPSling is the configuration for the HTTPSling client - HTTPSling *httpsling.Config // Interceptors are the request interceptors for the graph client Interceptors []clientv2.RequestInterceptor // Credentials are the credentials for the client @@ -42,14 +37,7 @@ var defaultClientConfig = Config{ Scheme: "http", Host: "localhost:17608", }, - GraphQLPath: "/query", - HTTPSling: &httpsling.Config{ - Headers: &http.Header{ - "Accept": []string{httpsling.ContentTypeJSONUTF8}, - "Accept-Language": []string{"en-US,en"}, - "Content-Type": []string{httpsling.ContentTypeJSONUTF8}, - }, - }, + GraphQLPath: "/query", Interceptors: []clientv2.RequestInterceptor{}, Clientv2Options: clientv2.Options{ParseDataAlongWithErrors: false}, } diff --git a/pkg/openlaneclient/creds.go b/pkg/openlaneclient/creds.go index 77c55dc3..43432b1e 100644 --- a/pkg/openlaneclient/creds.go +++ b/pkg/openlaneclient/creds.go @@ -4,9 +4,9 @@ import ( "net/http" "strings" + "github.com/theopenlane/httpsling" "github.com/theopenlane/utils/rout" - "github.com/theopenlane/httpsling" "github.com/theopenlane/iam/sessions" ) @@ -63,11 +63,7 @@ func (a Authorization) SetAuthorizationHeader(req *http.Request) { // ignore error as we are setting the header token, _ := a.AccessToken() - auth := httpsling.BearerAuth{ - Token: token, - } - - auth.Apply(req) + req.Header.Set(httpsling.HeaderAuthorization, httpsling.BearerAuthHeader+token) } } diff --git a/pkg/openlaneclient/options.go b/pkg/openlaneclient/options.go index 30031ecc..25a3861d 100644 --- a/pkg/openlaneclient/options.go +++ b/pkg/openlaneclient/options.go @@ -12,14 +12,6 @@ import ( // ClientOption allows us to configure the APIv1 client when it is created type ClientOption func(c *APIv1) error -// WithClient sets the client for the APIv1 client -func WithClient(client *httpsling.Client) ClientOption { - return func(c *APIv1) error { - c.HTTPSlingClient = client - return nil - } -} - // WithCredentials sets the credentials for the APIv1 client func WithCredentials(creds Credentials) ClientOption { return func(c *APIv1) error { @@ -34,17 +26,7 @@ func WithCredentials(creds Credentials) ClientOption { c.Config.Interceptors = append(c.Config.Interceptors, auth.WithAuthorization()) // Set the bearer token for the HTTPSling client, used for REST requests - c.Config.HTTPSling.Headers.Set(httpsling.HeaderAuthorization, "Bearer "+auth.BearerToken) - - return nil - } -} - -// WithHTTPSlingConfig sets the config for the APIv1 client -func WithHTTPSlingConfig(config *httpsling.Config) ClientOption { - return func(c *APIv1) error { - c.Config.HTTPSling = config - return nil + return c.Requester.Apply(httpsling.BearerAuth(auth.BearerToken)) } } @@ -79,16 +61,15 @@ func WithBaseURL(baseURL *url.URL) ClientOption { c.Config.BaseURL = baseURL // Set the base URL for the HTTPSling client - c.Config.HTTPSling.BaseURL = baseURL.String() - - return nil + return c.Requester.Apply(httpsling.URL(baseURL.String())) } } // WithTransport sets the transport for the APIv1 client func WithTransport(transport http.RoundTripper) ClientOption { return func(c *APIv1) error { - c.Config.HTTPSling.Transport = transport + c.Requester.HTTPClient().Transport = transport + return nil } } diff --git a/pkg/openlaneclient/restclient.go b/pkg/openlaneclient/restclient.go index 3adf77ea..305d9f7c 100644 --- a/pkg/openlaneclient/restclient.go +++ b/pkg/openlaneclient/restclient.go @@ -2,7 +2,9 @@ package openlaneclient import ( "context" - "net/http" + + "github.com/theopenlane/httpsling" + "github.com/theopenlane/httpsling/httpclient" "github.com/theopenlane/core/pkg/models" ) @@ -35,17 +37,21 @@ func NewRestClient(config Config, opts ...ClientOption) (_ OpenlaneRestClient, e Config: config, } - // Apply our options - for _, opt := range opts { - if err := opt(c); err != nil { + // create the HTTP sling requester if it is not set with the default client + if c.Requester == nil { + c.Requester, err = httpsling.New( + httpsling.Client( + httpclient.CookieJar(nil), // Use a cookie jar to store session cookies + ), + ) + if err != nil { return nil, err } } - // create the HTTP sling client if it is not set - if c.HTTPSlingClient == nil { - c.HTTPSlingClient, err = newHTTPClient(c.Config) - if err != nil { + // Apply our options + for _, opt := range opts { + if err := opt(c); err != nil { return nil, err } } @@ -58,20 +64,17 @@ var _ OpenlaneRestClient = &APIv1{} // Register a new user with the API func (s *APIv1) Register(ctx context.Context, in *models.RegisterRequest) (out *models.RegisterReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodPost, "/v1/register") - req.Body(in) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Post(v1Path("register")), + httpsling.Body(in)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newRequestError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newRequestError(resp.StatusCode, out.Error) } return out, nil @@ -79,20 +82,17 @@ func (s *APIv1) Register(ctx context.Context, in *models.RegisterRequest) (out * // Login to the API func (s *APIv1) Login(ctx context.Context, in *models.LoginRequest) (out *models.LoginReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodPost, "/v1/login") - req.Body(in) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Post(v1Path("login")), + httpsling.Body(in)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newAuthenticationError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newAuthenticationError(resp.StatusCode, out.Error) } return out, nil @@ -100,20 +100,17 @@ func (s *APIv1) Login(ctx context.Context, in *models.LoginRequest) (out *models // Refresh a user's access token func (s *APIv1) Refresh(ctx context.Context, in *models.RefreshRequest) (out *models.RefreshReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodPost, "/v1/refresh") - req.Body(in) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Post(v1Path("refresh")), + httpsling.Body(in)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newAuthenticationError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newAuthenticationError(resp.StatusCode, out.Error) } return out, nil @@ -121,20 +118,17 @@ func (s *APIv1) Refresh(ctx context.Context, in *models.RefreshRequest) (out *mo // Switch the current organization context func (s *APIv1) Switch(ctx context.Context, in *models.SwitchOrganizationRequest) (out *models.SwitchOrganizationReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodPost, "/v1/switch") - req.Body(in) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Post(v1Path("switch")), + httpsling.Body(in)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newAuthenticationError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newAuthenticationError(resp.StatusCode, out.Error) } return out, nil @@ -142,20 +136,17 @@ func (s *APIv1) Switch(ctx context.Context, in *models.SwitchOrganizationRequest // VerifyEmail verifies the email address of a user func (s *APIv1) VerifyEmail(ctx context.Context, in *models.VerifyRequest) (out *models.VerifyReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodGet, "/v1/verify") - req.Query("token", in.Token) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Get(v1Path("verify")), + httpsling.QueryParam("token", in.Token)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newRequestError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newRequestError(resp.StatusCode, out.Error) } return out, nil @@ -163,20 +154,17 @@ func (s *APIv1) VerifyEmail(ctx context.Context, in *models.VerifyRequest) (out // ResendEmail resends the verification email to the user func (s *APIv1) ResendEmail(ctx context.Context, in *models.ResendRequest) (out *models.ResendReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodPost, "/v1/resend") - req.Body(in) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Post(v1Path("resend")), + httpsling.Body(in)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newRequestError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newRequestError(resp.StatusCode, out.Error) } return out, nil @@ -184,20 +172,17 @@ func (s *APIv1) ResendEmail(ctx context.Context, in *models.ResendRequest) (out // ForgotPassword sends a password reset email to the user func (s *APIv1) ForgotPassword(ctx context.Context, in *models.ForgotPasswordRequest) (out *models.ForgotPasswordReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodPost, "/v1/forgot-password") - req.Body(in) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Post(v1Path("forgot-password")), + httpsling.Body(in)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newRequestError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newRequestError(resp.StatusCode, out.Error) } return out, nil @@ -205,20 +190,17 @@ func (s *APIv1) ForgotPassword(ctx context.Context, in *models.ForgotPasswordReq // ResetPassword resets the user's password func (s *APIv1) ResetPassword(ctx context.Context, in *models.ResetPasswordRequest) (out *models.ResetPasswordReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodPost, "/v1/password-reset") - req.Body(in) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Post(v1Path("password-reset")), + httpsling.Body(in)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newRequestError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newRequestError(resp.StatusCode, out.Error) } return out, nil @@ -226,20 +208,17 @@ func (s *APIv1) ResetPassword(ctx context.Context, in *models.ResetPasswordReque // AcceptInvite accepts an invite to join an organization func (s *APIv1) AcceptInvite(ctx context.Context, in *models.InviteRequest) (out *models.InviteReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodGet, "/v1/invite") - req.Query("token", in.Token) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Get(v1Path("invite")), + httpsling.QueryParam("token", in.Token)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newRequestError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newRequestError(resp.StatusCode, out.Error) } return out, nil @@ -247,21 +226,22 @@ func (s *APIv1) AcceptInvite(ctx context.Context, in *models.InviteRequest) (out // VerifySubscriberEmail verifies the email address of a subscriber func (s *APIv1) VerifySubscriberEmail(ctx context.Context, in *models.VerifySubscribeRequest) (out *models.VerifySubscribeReply, err error) { - req := s.HTTPSlingClient.NewRequestBuilder(http.MethodGet, "/v1/subscribe/verify") - req.Query("token", in.Token) - - resp, err := req.Send(ctx) + resp, err := s.Requester.ReceiveWithContext(ctx, &out, + httpsling.Get(v1Path("subscribe/verify")), + httpsling.QueryParam("token", in.Token)) if err != nil { return nil, err } - if err := resp.ScanJSON(&out); err != nil { - return nil, err - } + defer resp.Body.Close() - if !resp.IsSuccess() { - return nil, newRequestError(resp.StatusCode(), out.Error) + if !httpsling.IsSuccess(resp) { + return nil, newRequestError(resp.StatusCode, out.Error) } return out, nil } + +func v1Path(path string) string { + return "/v1/" + path +}