From 2d6b1156ce85d93eaf615992f8ecc71803d5a148 Mon Sep 17 00:00:00 2001 From: Stepan Rakitin Date: Fri, 12 Mar 2021 00:03:50 +0100 Subject: [PATCH] Add TLS client authentication --- docs/index.md | 19 +++++- go.mod | 3 +- go.sum | 17 ----- internal/provider/fixtures/tls.crt | 16 +++++ internal/provider/fixtures/tls.key | 28 ++++++++ internal/provider/provider.go | 106 +++++++++++++++++++++-------- internal/provider/provider_test.go | 48 ++++++++++++- 7 files changed, 189 insertions(+), 48 deletions(-) create mode 100644 internal/provider/fixtures/tls.crt create mode 100644 internal/provider/fixtures/tls.key diff --git a/docs/index.md b/docs/index.md index 208645a..9a473a9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,6 +22,7 @@ provider "hydra" { ``` + ## Schema ### Required @@ -33,16 +34,32 @@ provider "hydra" { - **authentication** (Block List, Max: 1) Optional block to specify an authentication method which is used to access Hydra Admin API. (see [below for nested schema](#nestedblock--authentication)) + ### Nested Schema for `authentication` Optional: - **basic** (Block List, Max: 1) (see [below for nested schema](#nestedblock--authentication--basic)) +- **tls** (Block List, Max: 1) (see [below for nested schema](#nestedblock--authentication--tls)) + ### Nested Schema for `authentication.basic` Required: - **password** (String, Sensitive) -- **username** (String) \ No newline at end of file +- **username** (String) + + + +### Nested Schema for `authentication.tls` + +Required: + +- **certificate** (String, Sensitive) PEM-encoded client certificate for TLS authentication. +- **key** (String, Sensitive) PEM-encoded client certificate key for TLS authentication. + +Optional: + +- **insecure_skip_verify** (Boolean) Controls whether a client verifies the server's certificate chain and host name. diff --git a/go.mod b/go.mod index fce6b82..11707a6 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ module github.com/svrakitin/terraform-provider-hydra -go 1.15 +go 1.16 require ( github.com/go-openapi/runtime v0.19.26 + github.com/hashicorp/go-cleanhttp v0.5.1 github.com/hashicorp/terraform-plugin-docs v0.4.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.3 github.com/mitchellh/mapstructure v1.4.0 diff --git a/go.sum b/go.sum index daec212..0aa4e7e 100644 --- a/go.sum +++ b/go.sum @@ -50,13 +50,10 @@ github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXva github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/apparentlymart/go-cidr v1.0.1 h1:NmIwLZ/KdsjIUlhf+/Np40atNXm/+lZ5txfTJ/SpF+U= github.com/apparentlymart/go-cidr v1.0.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= @@ -67,7 +64,6 @@ github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbj github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -104,9 +100,7 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -114,7 +108,6 @@ github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc= github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk= github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= @@ -284,7 +277,6 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -309,7 +301,6 @@ github.com/hashicorp/go-hclog v0.15.0 h1:qMuK0wxsoW4D0ddCCYwPSTm4KQv1X1ke3WmPWZ0 github.com/hashicorp/go-hclog v0.15.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-plugin v1.3.0 h1:4d/wJojzvHV1I4i/rrjVaeuyxWrLzDE1mDCyDy8fXS8= github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= github.com/hashicorp/go-plugin v1.4.0 h1:b0O7rs5uiJ99Iu9HugEzsM67afboErkHUWddUSpUO3A= github.com/hashicorp/go-plugin v1.4.0/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= @@ -344,7 +335,6 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKe github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -396,19 +386,16 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mitchellh/cli v1.1.1 h1:J64v/xD7Clql+JVKSvkYojLOXu1ibnY9ZjGLwSt/89w= github.com/mitchellh/cli v1.1.1/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw= github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= @@ -449,7 +436,6 @@ github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAv github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -497,7 +483,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.7.1 h1:AvsC01GMhMLFL8CgEYdHGM+yLnnDOwhPAYcgTkeF0Gw= github.com/zclconf/go-cty v1.7.1/go.mod h1:VDR4+I79ubFBGm1uJac1226K5yANQFHeauxPBoP54+o= @@ -528,7 +513,6 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -777,7 +761,6 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= diff --git a/internal/provider/fixtures/tls.crt b/internal/provider/fixtures/tls.crt new file mode 100644 index 0000000..e5cd0b8 --- /dev/null +++ b/internal/provider/fixtures/tls.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICljCCAX4CCQDZrefRfYETxTANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJE +RTAeFw0yMTAzMTEyMjIyNDNaFw0yMTA0MTAyMjIyNDNaMA0xCzAJBgNVBAYTAkRF +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3OSxw6wF1jEhRCgPw5zq +Tbk9OQ5boTWT+5hFfzT5RzShhPO7/rFZLJgcdLhNp/fpuKrtTxiLcSpfcnzYqzx6 +vZCp09Aq9fXcWy0igGZgaMi9ysZDUnDrm5ZQLMgLxakdSC6vhI86k56DDb6mnyCb +TBdqLDxRgg+THGicBSwJEhOMRU76AYfxxok8+ieJtGRq+uoZm9bC3l4fHV3aLEoc +YU6TNx5ocBdIlzEooKQW8xYF3XuQwkX+ceLGXm67XezHhEnEbS5uUZXih/Nw+EQH +FcPi58FbxIuHJ6s8T1XQY4bOK4PFtUEZa66UHyL5vcBGD2t9x803f7wGjrJCd2nE +jwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBHNjATaVbn9HyydNz9cxcKLEv/GQqC +ULbE6LDN3HZHkw45xGSSfaWc4+3jGpgO7Dxvs/I2q/WQ8Uo6gfBbD2F/TNDG3W1L +xdl3nvyMMtoATPH6A77aQR0m3uOBSrIUnjZGerjdAInSn/O9avN0AvcRoeKJ6ojg +1nyHWFfRrgKpESQ8BU+Aq6lzBfPGBy9NaZynsCKtG/Ju/IZyNkv2f8Sw2unvpYoa +EVBjuJd0RJ+HbFCaNGd2YXp9Eu2wJmr2GDra413MEED2ZsSlhg44EO0Jgo78Qmww +QJtjeT8yBSwSCaGsAKVzXxOzxYFBCVLuX8GxpCeSQP7GJV6LSDwxR5Ko +-----END CERTIFICATE----- diff --git a/internal/provider/fixtures/tls.key b/internal/provider/fixtures/tls.key new file mode 100644 index 0000000..6517ad1 --- /dev/null +++ b/internal/provider/fixtures/tls.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDc5LHDrAXWMSFE +KA/DnOpNuT05DluhNZP7mEV/NPlHNKGE87v+sVksmBx0uE2n9+m4qu1PGItxKl9y +fNirPHq9kKnT0Cr19dxbLSKAZmBoyL3KxkNScOubllAsyAvFqR1ILq+EjzqTnoMN +vqafIJtMF2osPFGCD5McaJwFLAkSE4xFTvoBh/HGiTz6J4m0ZGr66hmb1sLeXh8d +XdosShxhTpM3HmhwF0iXMSigpBbzFgXde5DCRf5x4sZebrtd7MeEScRtLm5RleKH +83D4RAcVw+LnwVvEi4cnqzxPVdBjhs4rg8W1QRlrrpQfIvm9wEYPa33HzTd/vAaO +skJ3acSPAgMBAAECggEBAMmoZrkR9IokdBA62plkSWsHb2MFPpWfyidoThnhjKl6 +3PH5aWkNEzHo9CGCmDJ923thYCBTcgmv+08TtuIs5ojk5oWeh3ngKHl8bQD3dZBz +owDZm2BKAm4Z/bvELSsYRsk9BbNo5rsZfN8xa//dzqjav2z+7BJmkZDf13/JQcaj +K6oeNnuogQ+cY9yXe0G0c5FHVqNhs+x2CITtnZtjcO1y/h83okpN4kCdD6h2ICxe +N5FaOYG+KTsDdnQwRtDsCXXFeBHcdzQBpVRCCFDqOWccOPA367xGmhWMY8txYk6n +18i+CX9hhQKJzIe7wrT9xXIJ5/sA9JKRdtB89MeVVUECgYEA8jTWs+bRkX8hzEW4 +3TRvElFG6xQha8ltBsYwE8w1xFNHapEDeUHzDLWUxhTzI0EYi/jyaahrbqpC9M5z +gd2HFoopnpdnNLMZNesHD0pk5OpthLC7WkIoJtLrQdmovTzAmwWS/cizaO1R7bk5 +O35/rRmaIBfRL19cu2cDzegotp8CgYEA6XkhKeYsVtkVBBIZDB3+EdL72OH9RzTw +UhmfoZctX5/bp2Tuhcbb/ztJ5+RU4NLd348A7fQf822CkAEZ0n0kRonn82qrVNSG +RSkq71zsU/FpqBcz5E9dz/SafYufCGuK008yiU+LD4IW7UPyYDjDfgwlt8t8C+Bw +O057hhMb3BECgYEAx+PxueFp3aFFfHeiPPVUIZLwa3xepL1E/I0+CmjDivaL/xgU +/NL/yuJlGSEbFGJZ5tMbBTYZC+j6f12PGIOCRIjcFmWvqF+TE9uXJPhp0j7jCdpt +lOz6hCgYPm1rBFqKPqZYDJjB8HvD3OS7pi0dI/f4KjpdyrHyLzuyeRH739MCgYEA +iuEK4SmR5ndrEOjTDWop3+Bo/zIuv1S2P6AOXMjYrLEisAhR+jG4W7Kg29fuxW2p +nXorS2CUQPE7YP3GpnbaRTtzRlCFagihdjJu38OesLBB8UMcEwtC+pi97UBIcXHH +Ors5jIRMbAUuLiTk4Gfjoe8H4LSiLU5sdFrTD4X+ZIECgYEAvdz7XlH79yphDIkz +dCoKIkzNjTBFogq4g46GjrJnFT8lrPBF5ZsdXCkN4GKCtwJUokfdeI4uovl2ZS9A +d9amtitSrc4wWElEVNyfp1vmGZNG8zdkUgI72sc8cyfyMxGi8Fc5zKHkYc+jy64M ++gY9aDXTWgXpIkhgPnSvFtL7qIs= +-----END PRIVATE KEY----- diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 59a25b9..b2db009 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1,12 +1,14 @@ package provider import ( + "bytes" "context" + "crypto/tls" "net/http" "net/url" - "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" + "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" hydraclient "github.com/ory/hydra-client-go/client" @@ -51,6 +53,35 @@ func New() *schema.Provider { }, }, }, + "tls": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "insecure_skip_verify": { + Type: schema.TypeBool, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("HYDRA_ADMIN_TLS_AUTH_INSECURE", false), + Description: "Controls whether a client verifies the server's certificate chain and host name.", + }, + "certificate": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + DefaultFunc: schema.EnvDefaultFunc("HYDRA_ADMIN_TLS_AUTH_CERT_DATA", nil), + Description: "PEM-encoded client certificate for TLS authentication.", + }, + "key": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + DefaultFunc: schema.EnvDefaultFunc("HYDRA_ADMIN_TLS_AUTH_KEY_DATA", nil), + Description: "PEM-encoded client certificate key for TLS authentication.", + }, + }, + }, + }, }, }, }, @@ -74,46 +105,65 @@ func providerConfigure(ctx context.Context, data *schema.ResourceData) (interfac return nil, diag.FromErr(err) } - transportConfig := &hydraclient.TransportConfig{ - Schemes: []string{endpointURL.Scheme}, - Host: endpointURL.Host, - BasePath: endpointURL.Path, + httpClient, err := configureHTTPClient(data) + if err != nil { + return nil, diag.FromErr(err) + } + + client := hydraclient.New( + httptransport.NewWithClient( + endpointURL.Host, + endpointURL.Path, + []string{endpointURL.Scheme}, + httpClient, + ), + nil, + ) + + return client.Admin, nil +} + +func configureHTTPClient(data *schema.ResourceData) (*http.Client, error) { + httpTransport := cleanhttp.DefaultPooledTransport() + httpClient := &http.Client{ + Transport: httpTransport, + } + + if tlsAuth, ok := data.GetOk("authentication.0.tls.0"); ok { + auth := tlsAuth.(map[string]interface{}) + certificate := bytes.NewBufferString(auth["certificate"].(string)).Bytes() + key := bytes.NewBufferString(auth["key"].(string)).Bytes() + insecureSkipVerify := auth["insecure_skip_verify"].(bool) + + cert, err := tls.X509KeyPair(certificate, key) + if err != nil { + return nil, err + } + + httpTransport.TLSClientConfig = &tls.Config{ + Certificates: []tls.Certificate{cert}, + InsecureSkipVerify: insecureSkipVerify, + } } - var transport runtime.ClientTransport if basicAuth, ok := data.GetOk("authentication.0.basic.0"); ok { auth := basicAuth.(map[string]interface{}) - httpClient := &http.Client{ - Transport: &BasicAuthTransport{ - username: auth["username"].(string), - password: auth["password"].(string), - RoundTripper: http.DefaultTransport, - }, + httpClient.Transport = &BasicAuthTransport{ + username: auth["username"].(string), + password: auth["password"].(string), + Wrapped: httpTransport, } - transport = httptransport.NewWithClient( - transportConfig.Host, - transportConfig.BasePath, - transportConfig.Schemes, - httpClient, - ) - } else { - transport = httptransport.New( - transportConfig.Host, - transportConfig.BasePath, - transportConfig.Schemes, - ) } - client := hydraclient.New(transport, nil) - return client.Admin, nil + return httpClient, nil } type BasicAuthTransport struct { username, password string - http.RoundTripper + Wrapped *http.Transport } func (bat *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) { req.SetBasicAuth(bat.username, bat.password) - return bat.RoundTripper.RoundTrip(req) + return bat.Wrapped.RoundTrip(req) } diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 8a16494..73d0423 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -1,6 +1,7 @@ package provider import ( + "crypto/tls" "fmt" "net/http" "net/http/httptest" @@ -44,7 +45,8 @@ func TestProvider_basicAuth(t *testing.T) { })) defer hydraAdminStub.Close() resource.Test(t, resource.TestCase{ - Providers: testAccProviders, + IsUnitTest: true, + Providers: testAccProviders, Steps: []resource.TestStep{ { Config: fmt.Sprintf(testAccProviderBasicAuthConfig, hydraAdminStub.URL, username, password), @@ -60,6 +62,32 @@ func TestProvider_basicAuth(t *testing.T) { }) } +func TestProvider_tlsAuth(t *testing.T) { + certFile := "./fixtures/tls.crt" + keyFile := "./fixtures/tls.key" + + hydraAdminStub := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + if len(req.TLS.PeerCertificates) == 0 { + w.WriteHeader(http.StatusBadRequest) + } + w.WriteHeader(http.StatusOK) + })) + hydraAdminStub.TLS.ClientAuth = tls.RequireAnyClientCert + defer hydraAdminStub.Close() + resource.Test(t, resource.TestCase{ + IsUnitTest: true, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(testAccProviderTLSAuthConfig, hydraAdminStub.URL, certFile, keyFile), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.hydra_jwks.test", "keys.#", "0"), + ), + }, + }, + }) +} + func testAccPreCheck(t *testing.T) { } @@ -76,6 +104,24 @@ provider "hydra" { } } +data "hydra_jwks" "test" { + name = "test" +} +` + + testAccProviderTLSAuthConfig string = ` +provider "hydra" { + endpoint = "%s" + + authentication { + tls { + insecure_skip_verify = true + certificate = file("%s") + key = file("%s") + } + } +} + data "hydra_jwks" "test" { name = "test" }