Compare commits

..

136 Commits

Author SHA1 Message Date
Hidetake Iwata
a993e39ed1 Update help message and doc (#1374) 2025-07-13 15:24:33 +09:00
Hidetake Iwata
7fc48592de Use Endpoint.DeviceAuthURL of oauth2 package (#1372) 2025-07-13 13:54:55 +09:00
Hidetake Iwata
fd9d3a8e9d Split oidc/client.go (#1371)
* Split oidc/client.go

* Refactor

* Fix

* Improve comment

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-13 13:23:33 +09:00
Hidetake Iwata
3981c78387 Add --oidc-request-header flag (#1359)
* fix(authcode): Set Origin header on token request

Allow passing Azure AD CORS checks.

on-behalf-of: @eon-se opensource@eon.com
Signed-off-by: Maximilian Blatt <maximilian.blatt.external@eon.com>

* Add `--oidc-request-header` flag

* Add doc

---------

Signed-off-by: Maximilian Blatt <maximilian.blatt.external@eon.com>
Co-authored-by: Maximilian Blatt <maximilian.blatt.external@eon.com>
2025-07-13 11:04:40 +09:00
renovate[bot]
8537977819 chore(deps): update module github.com/golangci/golangci-lint/v2 to v2.2.2 (#1370)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 17:10:18 +00:00
renovate[bot]
7e2658c061 fix(deps): update module golang.org/x/term to v0.33.0 (#1369)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-10 00:50:01 +00:00
renovate[bot]
346e7a5c9d fix(deps): update module golang.org/x/sync to v0.16.0 (#1368)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-09 22:09:38 +00:00
renovate[bot]
5ec3ec713f chore(deps): update dependency go to v1.24.5 (#1367)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-08 22:09:15 +00:00
renovate[bot]
0bdeca8526 chore(deps): update module github.com/golangci/golangci-lint/v2 to v2.2.1 (#1364)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-05 18:11:34 +00:00
renovate[bot]
dee7333343 chore(deps): update module github.com/vektra/mockery/v3 to v3.5.0 (#1365)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-05 17:07:43 +00:00
renovate[bot]
2c9980a400 fix(deps): update module github.com/chromedp/chromedp to v0.13.7 (#1363)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-20 08:13:40 +00:00
renovate[bot]
4b19fd7d43 fix(deps): update kubernetes packages to v0.33.2 (#1362)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-19 20:11:05 +00:00
renovate[bot]
04ba16a2dd chore(deps): update docker/setup-buildx-action action to v3.11.1 (#1361)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 15:10:02 +00:00
renovate[bot]
395cbb8ec0 chore(deps): update docker/setup-buildx-action action to v3.11.0 (#1360)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-16 19:07:31 +00:00
Hidetake Iwata
7bffbf1e99 Refactor transport package (#1358) 2025-06-16 18:48:24 +09:00
Hidetake Iwata
b2dbe2beda Refactor setup and usage docs (#1357)
* Refactor seup and usage docs

* Fix
2025-06-16 14:58:20 +09:00
Clay B.
cefacba2d2 Support Client Credentials Flow (#1231)
* Issue 931: Support Client Credentials Flow

* Move client-credentials to use --oidc-auth-request-extra-params

* Missed a file in moving to --oidc-auth-request-extra-params

* Support --oidc-use-access-token

* make generate

---------

Co-authored-by: Hidetake Iwata <int128@gmail.com>
2025-06-16 14:16:58 +09:00
Hidetake Iwata
0f2f54d4bf Add --oidc-redirect-url to override redirect URL (#1263) 2025-06-16 13:42:48 +09:00
renovate[bot]
a85488b4fc chore(deps): update module github.com/vektra/mockery/v3 to v3.4.0 (#1356)
* chore(deps): update module github.com/vektra/mockery/v3 to v3.4.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/15641401633

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-06-13 22:09:04 +00:00
renovate[bot]
064d67043c chore(deps): update module github.com/vektra/mockery/v3 to v3.3.6 (#1354)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-12 22:09:14 +00:00
renovate[bot]
67bcc29e3d chore(deps): update dependency go to v1.24.4 (#1349)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-09 20:10:32 +00:00
renovate[bot]
d24340b179 chore(deps): update module github.com/vektra/mockery/v3 to v3.3.4 (#1353)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-09 18:13:35 +00:00
renovate[bot]
56300e733e fix(deps): update module golang.org/x/sync to v0.15.0 (#1352)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-06 23:09:03 +00:00
renovate[bot]
e66ac72907 chore(deps): update module github.com/vektra/mockery/v3 to v3.3.3 (#1350)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-06 21:08:23 +00:00
renovate[bot]
ed98ee4b07 chore(deps): update int128/update-generated-files-action action to v2.60.0 (#1348)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-02 06:14:52 +00:00
renovate[bot]
ae6fc796d1 chore(deps): update module github.com/vektra/mockery/v3 to v3.3.2 (#1347)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-31 00:45:14 +00:00
renovate[bot]
12d5a73ed6 chore(deps): update int128/update-generated-files-action action to v2.59.0 (#1346)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-29 17:08:09 +00:00
renovate[bot]
6b78d60eb8 chore(deps): update module github.com/vektra/mockery/v3 to v3.3.1 (#1344)
* chore(deps): update module github.com/vektra/mockery/v3 to v3.3.1

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/15284039911

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-05-27 22:08:47 +00:00
renovate[bot]
1714508e08 chore(deps): update docker/build-push-action action to v6.18.0 (#1345)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-27 21:08:46 +00:00
renovate[bot]
1985d7246f chore(deps): update module github.com/vektra/mockery/v3 to v3.3.0 (#1343)
* chore(deps): update module github.com/vektra/mockery/v3 to v3.3.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/15264974955

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-05-27 05:09:47 +00:00
renovate[bot]
659ddc99e3 fix(deps): update module github.com/int128/oauth2dev to v1.1.0 (#1342)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-24 17:07:15 +00:00
renovate[bot]
a7bbe92827 fix(deps): update module github.com/int128/oauth2cli to v1.17.0 (#1341)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-20 21:08:25 +00:00
Hidetake Iwata
db764cd328 Use PKCE verifier of oauth2 package (#1340) 2025-05-19 18:51:43 +09:00
renovate[bot]
7af43af614 fix(deps): update module github.com/int128/oauth2cli to v1.16.0 (#1339)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-18 12:15:36 +00:00
renovate[bot]
c7342f301b chore(deps): update module github.com/vektra/mockery/v2 to v3 (#1322)
* chore(deps): update module github.com/vektra/mockery/v2 to v3

* Update config

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Hidetake Iwata <int128@gmail.com>
2025-05-17 10:28:43 +09:00
Hidetake Iwata
a4e614aa85 Update github.com/golangci/golangci-lint to v2 (#1336)
* Update github.com/golangci/golangci-lint to v2

* Handle io.Close()
2025-05-17 10:05:32 +09:00
renovate[bot]
6e6de231c2 fix(deps): update kubernetes packages to v0.33.1 (#1338)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-16 03:36:37 +00:00
renovate[bot]
35e8f00003 chore(deps): update docker/build-push-action action to v6.17.0 (#1337)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-15 14:09:54 +00:00
Clay B.
751f5f72c7 Provide a token-cache-storage type of none (#1285)
Co-authored-by: Hidetake Iwata <int128@gmail.com>
2025-05-13 21:52:09 +09:00
renovate[bot]
655ae5717b chore(deps): update int128/docker-build-cache-config-action action to v1.38.0 (#1335)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-08 13:23:00 +00:00
renovate[bot]
aa92832adb chore(deps): update actions/setup-go action to v5.5.0 (#1334)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-08 05:10:11 +00:00
renovate[bot]
f0a5aa7f6a chore(deps): update int128/update-generated-files-action action to v2.58.0 (#1333)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-08 03:35:31 +00:00
renovate[bot]
8c6ac0d3ff chore(deps): update dependency go to v1.24.3 (#1332)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-06 23:08:31 +00:00
renovate[bot]
127a4ace7c fix(deps): update module golang.org/x/term to v0.32.0 (#1331)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 21:57:53 +00:00
renovate[bot]
dd62bd0281 fix(deps): update module golang.org/x/oauth2 to v0.30.0 (#1328)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 20:10:27 +00:00
renovate[bot]
2794e6c805 fix(deps): update module golang.org/x/sync to v0.14.0 (#1329)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 18:10:34 +00:00
renovate[bot]
342ace8aec chore(deps): update docker/build-push-action action to v6.16.0 (#1326)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-24 18:11:41 +00:00
renovate[bot]
259303299e fix(deps): update kubernetes packages to v0.33.0 (#1325)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-24 00:44:35 +00:00
renovate[bot]
64b42f8f8c fix(deps): update kubernetes packages to v0.32.4 (#1324)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-23 12:16:59 +00:00
renovate[bot]
31f182cc37 chore(deps): update module github.com/golangci/golangci-lint to v1.64.8 (#1319)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-08 16:11:23 +00:00
renovate[bot]
57873e9338 chore(deps): update module github.com/vektra/mockery/v2 to v2.53.3 (#1320)
* chore(deps): update module github.com/vektra/mockery/v2 to v2.53.3

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/14334521272

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-04-08 15:09:55 +00:00
renovate[bot]
531792ba02 fix(deps): update module golang.org/x/term to v0.31.0 (#1318)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-06 03:27:18 +00:00
renovate[bot]
bd66f19bd5 fix(deps): update module golang.org/x/oauth2 to v0.29.0 (#1316)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-05 22:07:27 +00:00
renovate[bot]
951e1c4713 fix(deps): update module golang.org/x/sync to v0.13.0 (#1317)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-05 20:08:24 +00:00
renovate[bot]
aed6620066 fix(deps): update module github.com/coreos/go-oidc/v3 to v3.14.1 (#1315)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-04 00:43:07 +00:00
renovate[bot]
140b612357 fix(deps): update module github.com/chromedp/chromedp to v0.13.6 (#1314)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-03 08:12:27 +00:00
renovate[bot]
efc5ce1571 chore(deps): update dependency go to v1.24.2 (#1312)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 02:20:24 +00:00
renovate[bot]
c20af93fd4 fix(deps): update module github.com/chromedp/chromedp to v0.13.5 (#1313)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 00:43:44 +00:00
renovate[bot]
6c7e7f7dad fix(deps): update module github.com/golang-jwt/jwt/v5 to v5.2.2 (#1311)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-21 23:08:17 +00:00
renovate[bot]
1af1bb2910 fix(deps): update module github.com/chromedp/chromedp to v0.13.3 (#1310)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-21 05:08:59 +00:00
renovate[bot]
e1863154df fix(deps): update module github.com/chromedp/chromedp to v0.13.2 (#1309)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 03:20:40 +00:00
renovate[bot]
c7736355b6 chore(deps): update actions/setup-go action to v5.4.0 (#1308)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-19 05:09:13 +00:00
renovate[bot]
93d83b9365 chore(deps): update docker/login-action action to v3.4.0 (#1306)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-14 12:15:29 +00:00
renovate[bot]
d5f9e3c88e fix(deps): update module github.com/coreos/go-oidc/v3 to v3.13.0 (#1305)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-13 13:18:53 +00:00
renovate[bot]
4d10746b42 fix(deps): update kubernetes packages to v0.32.3 (#1303)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-12 13:18:26 +00:00
renovate[bot]
b26cd49178 fix(deps): update module github.com/chromedp/chromedp to v0.13.1 (#1302)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-06 02:14:53 +00:00
renovate[bot]
19aeb78113 chore(deps): update dependency go to v1.24.1 (#1298)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-06 00:41:54 +00:00
renovate[bot]
b359f0de12 fix(deps): update module golang.org/x/oauth2 to v0.28.0 (#1299)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-05 22:08:14 +00:00
renovate[bot]
c91e9bee42 fix(deps): update module golang.org/x/term to v0.30.0 (#1301)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-05 20:09:44 +00:00
renovate[bot]
88fb3c2ea8 fix(deps): update module golang.org/x/sync to v0.12.0 (#1300)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-05 18:12:12 +00:00
Hidetake Iwata
751469d3b9 Use int128/docker-build-metadata-action (#1297)
* Use int128/docker-build-metadata-action

* Fix conditional check in Docker workflow
2025-03-01 17:08:18 +09:00
renovate[bot]
c29ab9c8ce chore(deps): update docker/setup-qemu-action action to v3.6.0 (#1296)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-28 16:10:39 +00:00
renovate[bot]
19e4da8f4d chore(deps): update docker/build-push-action action to v6.15.0 (#1290)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-27 02:13:35 +00:00
renovate[bot]
fcb4a27cde chore(deps): update docker/setup-buildx-action action to v3.10.0 (#1292)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-27 00:41:08 +00:00
renovate[bot]
021bc77094 chore(deps): update docker/setup-qemu-action action to v3.5.0 (#1293)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-26 23:08:26 +00:00
renovate[bot]
f9367d6fd1 chore(deps): update docker/metadata-action action to v5.7.0 (#1291)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-26 21:07:51 +00:00
renovate[bot]
516d8bae41 fix(deps): update module golang.org/x/oauth2 to v0.27.0 (#1288)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-24 20:09:54 +00:00
renovate[bot]
22153cc1f4 fix(deps): update module github.com/chromedp/chromedp to v0.13.0 (#1287)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-22 07:07:04 +00:00
renovate[bot]
45dd932876 fix(deps): update module github.com/google/go-cmp to v0.7.0 (#1286)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-22 00:38:46 +00:00
renovate[bot]
6b108ffb9d chore(deps): update docker/build-push-action action to v6.14.0 (#1284)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-19 19:06:43 +00:00
renovate[bot]
cf3063c3bf fix(deps): update module github.com/spf13/cobra to v1.9.1 (#1283)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-17 04:10:52 +00:00
renovate[bot]
c7060d2ca5 fix(deps): update module github.com/spf13/cobra to v1.9.0 (#1282)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-15 20:07:44 +00:00
renovate[bot]
8002eeb191 fix(deps): update kubernetes packages to v0.32.2 (#1281)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-13 20:08:58 +00:00
Hidetake Iwata
b95872b24f Migrate to go tool (#1280)
* Migrate to go tool

* Fix
2025-02-13 21:29:58 +09:00
renovate[bot]
2d5775315f fix(deps): update module github.com/golangci/golangci-lint to v1.64.4 (#1278)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-13 03:12:44 +00:00
renovate[bot]
ba2e5e5fea chore(deps): update dependency go to v1.24.0 (#1275)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-13 02:09:21 +00:00
renovate[bot]
525cdae92d chore(deps): update golang docker tag to v1.24 (#1279)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-13 00:40:15 +00:00
renovate[bot]
30b7f47e70 fix(deps): update module github.com/vektra/mockery/v2 to v2.52.2 (#1277)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.52.2

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/13279561144

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-02-12 08:11:22 +00:00
renovate[bot]
284cd851ea fix(deps): update module github.com/golangci/golangci-lint to v1.64.2 (#1276)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-12 00:40:02 +00:00
renovate[bot]
4cf5b302fe chore(deps): update docker/setup-buildx-action action to v3.9.0 (#1273)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-06 20:08:46 +00:00
renovate[bot]
63dcbeb6f5 chore(deps): update dependency go to v1.23.6 (#1269)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-06 18:10:51 +00:00
renovate[bot]
ea6b3815bf chore(deps): update docker/setup-qemu-action action to v3.4.0 (#1274)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-06 16:08:34 +00:00
renovate[bot]
a5f746ad6e fix(deps): update module golang.org/x/sync to v0.11.0 (#1271)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-04 21:12:58 +00:00
renovate[bot]
434c69407e fix(deps): update module golang.org/x/term to v0.29.0 (#1272)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-04 20:08:51 +00:00
renovate[bot]
8ec95ed141 fix(deps): update module golang.org/x/oauth2 to v0.26.0 (#1270)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-04 19:06:19 +00:00
renovate[bot]
dee9032023 fix(deps): update module github.com/vektra/mockery/v2 to v2.52.1 (#1268)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.52.1

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/13085455877

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-02-01 08:09:43 +00:00
renovate[bot]
cb7a9742ac fix(deps): update module github.com/int128/oauth2cli to v1.15.1 (#1262)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-01 05:07:30 +00:00
renovate[bot]
a3013a12b9 fix(deps): update module github.com/spf13/pflag to v1.0.6 (#1266)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-30 12:22:57 +00:00
Hidetake Iwata
bc7e71f586 Change default token cache storage to disk (#1264)
* Change default token cache storage to disk

* Fix

* Fix

* Clean up both storages
2025-01-30 18:47:07 +09:00
Hidetake Iwata
19d61e70a9 Fix client secret description (#1265) 2025-01-26 16:04:14 +09:00
Hidetake Iwata
3a38753ee7 Refactor setup command and docs (#1253)
* Refactor setup command and docs

* Fix slice flags

* Fix
2025-01-25 16:08:28 +09:00
Johannes Edelstam
56e09ad65e Update instructions for Google OAuth (#1260) 2025-01-25 10:04:12 +09:00
Johannes Edelstam
58a4b1399f Use homebrew main tap (#1259)
Since kubelogin exists in the homebrew main tap use that instead.
2025-01-25 10:02:43 +09:00
James White
6726d851cb Fallback to disk storage if too big for keyring (#1257) 2025-01-25 09:54:28 +09:00
renovate[bot]
21e03dc294 chore(deps): update docker/build-push-action action to v6.13.0 (#1261)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-24 14:07:45 +00:00
renovate[bot]
5f1ed82a85 fix(deps): update module github.com/chromedp/chromedp to v0.12.1 (#1258)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-23 08:11:34 +00:00
renovate[bot]
abb1a564f4 chore(deps): update actions/setup-go action to v5.3.0 (#1256)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-21 11:06:49 +00:00
renovate[bot]
6d4eee5d1d fix(deps): update module github.com/vektra/mockery/v2 to v2.51.1 (#1254)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.51.1

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12861944941

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-01-20 08:12:01 +00:00
Hidetake Iwata
4c10146639 Refactor integration-test and acceptance-test (#1252)
* Refactor tests

* Fix

* Run plugin

* Fix

* Update acceptance-test.yaml

* Fix
2025-01-20 09:37:10 +09:00
Hidetake Iwata
3121e55498 Update apiVersion to client.authentication.k8s.io/v1 (integration-test) (#1251) 2025-01-19 17:58:55 +09:00
Hidetake Iwata
a2a6ea229d Improve docs (#1250)
* Refactor docs

* Update --exec-api-version

* Add device authorization grant

* Fix
2025-01-19 15:02:02 +09:00
Rahul Somasundaram
e7819f15eb Added windows arm64 release (#1244)
Co-authored-by: Hidetake Iwata <int128@gmail.com>
2025-01-19 11:12:57 +09:00
renovate[bot]
6099a60aad chore(deps): update dependency go to v1.23.5 (#1249)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-18 15:06:31 +00:00
Hidetake Iwata
e31ad59e63 Add clean command (#1248)
* Add clean command

* Refactor

* Refactor
2025-01-18 22:24:23 +09:00
renovate[bot]
355d9cf224 fix(deps): update kubernetes packages to v0.32.1 (#1246)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-16 15:08:01 +00:00
renovate[bot]
fb5cfcf18f chore(deps): update docker/build-push-action action to v6.12.0 (#1247)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-16 13:14:40 +00:00
renovate[bot]
31fadd2569 chore(deps): update int128/update-generated-files-action action to v2.57.0 (#1245)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-15 12:14:48 +00:00
renovate[bot]
9f55437307 fix(deps): update module github.com/vektra/mockery/v2 to v2.51.0 (#1243)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.51.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12764870470

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-01-14 12:14:38 +00:00
Hidetake Iwata
aa1f445672 Rename flag to --oidc-pkce-method and improve docs (#1240)
* Add --oidc-pkce-method and improve docs

* Fix lint

* Refactor

* Refactor
2025-01-14 09:57:19 +09:00
Hidetake Iwata
0c160f9db2 Refactor integration-test (#1242)
* Refactor integration-test

* Refactor
2025-01-13 16:29:27 +09:00
Hidetake Iwata
8c7903b2db Test PKCE by default (integration-test) (#1241) 2025-01-13 15:50:48 +09:00
Hidetake Iwata
898e8a12de Refactor PKCE implementation (#1239) 2025-01-12 21:41:20 +09:00
Hidetake Iwata
606f1cd0b6 Remove unused struct field (#1238) 2025-01-12 15:55:26 +09:00
Hidetake Iwata
562b998ca7 Add [SECURITY RISK] to insecure flag description (#1237) 2025-01-12 15:17:47 +09:00
Hidetake Iwata
6c9d198ef5 Add --token-cache-storage flag (#1236) 2025-01-12 14:55:46 +09:00
Hidetake Iwata
5ebecc534e Format markdown (#1235) 2025-01-12 14:00:03 +09:00
Hidetake Iwata
ca273c358d Refactor getDefaultTokenCacheDir() (#1234) 2025-01-12 13:36:28 +09:00
Hidetake Iwata
ccc6b772db Extract tokenCacheOptions (#1232)
* Extract tokenCacheOptions

* Refactor
2025-01-12 13:21:03 +09:00
Hidetake Iwata
1681d84fae Push container image on push event only (#1233) 2025-01-12 13:15:09 +09:00
Hidetake Iwata
6f62b25c40 Extract struct tokencache.Config (#1226) 2025-01-11 16:44:56 +09:00
renovate[bot]
71a7467e64 chore(deps): update docker/build-push-action action to v6.11.0 (#1228)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 18:11:18 +00:00
renovate[bot]
5c78b7823b chore(deps): update docker/setup-qemu-action action to v3.3.0 (#1229)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 16:09:57 +00:00
Hidetake Iwata
361c376c95 Enable keyring in system-test (#1225)
* Enable keyring in system-test

* Add dbus-run-session and gnome-keyring-daemon

* Fix

* Fix

* Refactor
2025-01-08 16:53:59 +09:00
Hidetake Iwata
c66570c030 Remove unused struct member (#1224) 2025-01-08 12:50:15 +09:00
kalle (jag)
afb25f511c Added key cache via OS keyring (#973)
* Added key cache via OS keyring

* Fix lint issue

* Disable keyring in integration tests

* Disable keyring in system test

---------

Co-authored-by: Hidetake Iwata <int128@gmail.com>
2025-01-08 12:32:26 +09:00
Hidetake Iwata
a836ef0e92 Do not push container image on fork (#1223) 2025-01-08 12:17:50 +09:00
117 changed files with 6479 additions and 5520 deletions

34
.github/workflows/acceptance-test.yaml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: acceptance-test
on:
pull_request:
branches:
- master
paths:
- .github/workflows/acceptance-test.yaml
- acceptance_test/**
push:
branches:
- master
paths:
- .github/workflows/acceptance-test.yaml
- acceptance_test/**
jobs:
test-makefile:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: go.mod
cache-dependency-path: go.sum
- run: make -C acceptance_test check
- run: make -C acceptance_test
env:
OIDC_ISSUER_URL: https://accounts.google.com
OIDC_CLIENT_ID: REDACTED.apps.googleusercontent.com
YOUR_EMAIL: REDACTED@gmail.com
- run: make -C acceptance_test delete-cluster
- run: make -C acceptance_test clean

View File

@@ -28,28 +28,28 @@ jobs:
contents: read
packages: write
outputs:
image-uri: ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
image-uri: ${{ steps.build-metadata.outputs.image-uri }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
- uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
id: metadata
with:
images: ghcr.io/${{ github.repository }}
- uses: int128/docker-build-cache-config-action@622932dfa73db7d3a65e40d5fcc094f2101e659a # v1.37.0
- uses: int128/docker-build-cache-config-action@338206c80bf9eeb2b9694b7b4fc8c247c317e2a8 # v1.38.0
id: cache
with:
image: ghcr.io/${{ github.repository }}/cache
- uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
- uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
id: build
with:
push: true
push: ${{ github.event_name == 'push' }}
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
cache-from: ${{ steps.cache.outputs.cache-from }}
@@ -58,8 +58,13 @@ jobs:
linux/amd64
linux/arm64
linux/ppc64le
- uses: int128/docker-build-metadata-action@fac3c879c58b212e339c5e959cabb865cbee0c6e # v1.0.0
id: build-metadata
with:
metadata: ${{ steps.build.outputs.metadata }}
test:
if: needs.build.outputs.image-uri != ''
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10

View File

@@ -30,7 +30,7 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: go.mod
cache-dependency-path: go.sum
@@ -48,7 +48,7 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: go.mod
cache-dependency-path: go.sum
@@ -59,10 +59,10 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: tools/go.mod
cache-dependency-path: tools/go.sum
go-version-file: go.mod
cache-dependency-path: go.sum
- run: make lint
generate:
@@ -70,10 +70,10 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: tools/go.mod
cache-dependency-path: tools/go.sum
go-version-file: go.mod
cache-dependency-path: go.sum
- run: go mod tidy
- run: make generate
- uses: int128/update-generated-files-action@7eb71af1ae8e30d970ea5512d23fd2f4b0eae44c # v2.56.0
- uses: int128/update-generated-files-action@f6dc44e35ce252932e9018f1c38d1e2a4ff80e14 # v2.60.0

View File

@@ -47,6 +47,9 @@ jobs:
- runs-on: windows-latest
GOOS: windows
GOARCH: amd64
- runs-on: windows-latest
GOOS: windows
GOARCH: arm64
runs-on: ${{ matrix.platform.runs-on }}
env:
GOOS: ${{ matrix.platform.GOOS }}
@@ -55,7 +58,7 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: go.mod
cache-dependency-path: go.sum

View File

@@ -23,16 +23,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: go.mod
cache-dependency-path: go.sum
# for certutil
- run: sudo apt-get update
# Install certutil.
# https://packages.ubuntu.com/xenial/libnss3-tools
- run: sudo apt update
- run: sudo apt install -y libnss3-tools
- run: mkdir -p ~/.pki/nssdb
# Install keyring related packages.
# https://github.com/zalando/go-keyring/issues/45
- run: sudo apt-get install --no-install-recommends -y libnss3-tools dbus-x11 gnome-keyring
- run: echo '127.0.0.1 dex-server' | sudo tee -a /etc/hosts

View File

@@ -60,3 +60,9 @@ spec:
matchLabels:
os: windows
arch: amd64
- bin: kubelogin.exe
{{ addURIAndSha "https://github.com/int128/kubelogin/releases/download/{{ .TagName }}/kubelogin_windows_arm64.zip" .TagName }}
selector:
matchLabels:
os: windows
arch: arm64

View File

@@ -1,6 +1,7 @@
outpkg: "{{.PackageName}}_mock"
dir: "mocks/{{.PackagePath}}_mock"
dir: mocks/{{.SrcPackagePath}}_mock
pkgname: '{{.SrcPackageName}}_mock'
filename: mocks.go
template: testify
packages:
github.com/int128/kubelogin:
config:
@@ -8,4 +9,4 @@ packages:
recursive: true
io:
interfaces:
Closer:
Closer: {}

View File

@@ -1,4 +1,4 @@
FROM --platform=$BUILDPLATFORM golang:1.23 AS builder
FROM --platform=$BUILDPLATFORM golang:1.24 AS builder
WORKDIR /builder

View File

@@ -11,12 +11,10 @@ integration-test:
.PHONY: generate
generate:
$(MAKE) -C tools
./tools/bin/wire ./pkg/di
go tool github.com/google/wire/cmd/wire ./pkg/di
rm -fr mocks/
./tools/bin/mockery
go tool mockery
.PHONY: lint
lint:
$(MAKE) -C tools
./tools/bin/golangci-lint run
go tool golangci-lint run

101
README.md
View File

@@ -13,7 +13,6 @@ Take a look at the diagram:
![Diagram of the credential plugin](docs/credential-plugin-diagram.svg)
## Getting Started
### Setup
@@ -22,7 +21,7 @@ Install the latest release from [Homebrew](https://brew.sh/), [Krew](https://git
```sh
# Homebrew (macOS and Linux)
brew install int128/kubelogin/kubelogin
brew install kubelogin
# Krew (macOS, Linux, Windows and ARM)
kubectl krew install oidc-login
@@ -31,28 +30,28 @@ kubectl krew install oidc-login
choco install kubelogin
```
If you install via GitHub releases, you need to put the `kubelogin` binary on your path under the name `kubectl-oidc_login` so that the [kubectl plugin mechanism](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/) can find it when you invoke `kubectl oidc-login`. The other install methods do this for you.
If you install via GitHub releases, save the binary as the name `kubectl-oidc_login` on your path.
When you invoke `kubectl oidc-login`, kubectl finds it by the [naming convention of kubectl plugins](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/).
The other install methods do this for you.
You need to set up the OIDC provider, cluster role binding, Kubernetes API server and kubeconfig.
The kubeconfig looks like:
Your kubeconfig looks like this:
```yaml
users:
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- --oidc-issuer-url=ISSUER_URL
- --oidc-client-id=YOUR_CLIENT_ID
- --oidc-client-secret=YOUR_CLIENT_SECRET
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: kubectl
args:
- oidc-login
- get-token
- --oidc-issuer-url=ISSUER_URL
- --oidc-client-id=YOUR_CLIENT_ID
```
See [setup guide](docs/setup.md) for more.
See the [setup guide](docs/setup.md) for more.
### Run
@@ -65,33 +64,46 @@ kubectl get pods
Kubectl executes kubelogin before calling the Kubernetes APIs.
Kubelogin automatically opens the browser, and you can log in to the provider.
<img src="docs/keycloak-login.png" alt="keycloak-login" width="455" height="329">
After the authentication, kubelogin returns the credentials to kubectl.
Kubectl then calls the Kubernetes APIs with the credentials.
After authentication, kubelogin returns the credentials to kubectl and kubectl then calls the Kubernetes APIs with these credentials.
```
```console
% kubectl get pods
Open http://localhost:8000 for authentication
NAME READY STATUS RESTARTS AGE
echoserver-86c78fdccd-nzmd5 1/1 Running 0 26d
```
Kubelogin writes the ID token and refresh token to the token cache file.
Kubelogin stores the ID token and refresh token to the cache.
If the ID token is valid, it just returns it.
If the ID token has expired, it will refresh the token using the refresh token.
If the refresh token has expired, it will perform re-authentication.
If the cached ID token is valid, kubelogin just returns it.
If the cached ID token has expired, kubelogin will refresh the token using the refresh token.
If the refresh token has expired, kubelogin will perform re-authentication (you will have to login via browser again).
## Troubleshooting
### Token cache
### Troubleshoot
Kubelogin stores the token cache to the file system by default.
For enhanced security, it is recommended to store it to the keyring.
See the [token cache](docs/usage.md#token-cache) for details.
You can log out by removing the token cache directory (default `~/.kube/cache/oidc-login`).
Kubelogin will ask you to login via browser again if the token cache file does not exist i.e., it starts with a clean slate
You can dump claims of an ID token by `setup` command.
You can log out by deleting the token cache.
```console
% kubectl oidc-login setup --oidc-issuer-url https://accounts.google.com --oidc-client-id REDACTED --oidc-client-secret REDACTED
% kubectl oidc-login clean
Deleted the token cache at /home/user/.kube/cache/oidc-login
Deleted the token cache from the keyring
```
Kubelogin will ask you to log in via the browser again.
If the browser has a cookie for the provider, you need to log out from the provider or clear the cookie.
### ID token claims
You can run `setup` command to dump the claims of an ID token from the provider.
```console
% kubectl oidc-login setup --oidc-issuer-url=ISSUER_URL --oidc-client-id=REDACTED
...
You got a token with the following claims:
@@ -103,23 +115,22 @@ You got a token with the following claims:
}
```
You can increase the log level by `-v1` option.
You can set `-v1` option to increase the log level.
```yaml
users:
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- -v1
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: kubectl
args:
- oidc-login
- get-token
- -v1
```
You can verify kubelogin works with your provider using [acceptance test](acceptance_test).
You can run the [acceptance test](acceptance_test) to verify if kubelogin works with your provider.
## Docs
@@ -129,11 +140,7 @@ You can verify kubelogin works with your provider using [acceptance test](accept
- [System test](system_test)
- [Acceptance_test for identity providers](acceptance_test)
## Contributions
This is an open source software licensed under Apache License 2.0.
Feel free to open issues and pull requests for improving code and documents.
This software is developed with [GoLand](https://www.jetbrains.com/go/) licensed for open source development.
Special thanks for the support.

View File

@@ -4,33 +4,38 @@ OUTPUT_DIR := $(CURDIR)/output
KUBECONFIG := $(OUTPUT_DIR)/kubeconfig.yaml
export KUBECONFIG
# create a Kubernetes cluster
.PHONY: cluster
cluster:
# create a cluster
# Create a cluster.
mkdir -p $(OUTPUT_DIR)
sed -e "s|OIDC_ISSUER_URL|$(OIDC_ISSUER_URL)|" -e "s|OIDC_CLIENT_ID|$(OIDC_CLIENT_ID)|" cluster.yaml > $(OUTPUT_DIR)/cluster.yaml
kind create cluster --name $(CLUSTER_NAME) --config $(OUTPUT_DIR)/cluster.yaml
# set up access control
# Set up the access control.
kubectl create clusterrole cluster-readonly --verb=get,watch,list --resource='*.*'
kubectl create clusterrolebinding cluster-readonly --clusterrole=cluster-readonly --user=$(YOUR_EMAIL)
# set up kubectl
# Set up kubectl.
kubectl config set-credentials oidc \
--exec-api-version=client.authentication.k8s.io/v1beta1 \
--exec-api-version=client.authentication.k8s.io/v1 \
--exec-interactive-mode=Never \
--exec-command=$(CURDIR)/../kubelogin \
--exec-arg=get-token \
--exec-arg=--token-cache-dir=$(OUTPUT_DIR)/token-cache \
--exec-arg=--oidc-issuer-url=$(OIDC_ISSUER_URL) \
--exec-arg=--oidc-client-id=$(OIDC_CLIENT_ID) \
--exec-arg=--oidc-client-secret=$(OIDC_CLIENT_SECRET) \
--exec-arg=--oidc-extra-scope=email
# switch the default user
# Switch the default user.
kubectl config set-context --current --user=oidc
# clean up the resources
# Show the kubeconfig.
kubectl config view
.PHONY: clean
clean:
-rm -r $(OUTPUT_DIR)
.PHONY: delete-cluster
delete-cluster:
kind delete cluster --name $(CLUSTER_NAME)

View File

@@ -1,16 +1,14 @@
# kubelogin/acceptance_test
This is a manual test for verifying Kubernetes OIDC authentication with your OIDC provider.
This is a manual test to verify if the Kubernetes OIDC authentication works with your OIDC provider.
## Purpose
This test checks the following points:
1. You can set up your OIDC provider using [setup guide](../docs/setup.md).
1. You can set up your OIDC provider using the [setup guide](../docs/setup.md).
1. The plugin works with your OIDC provider.
## Getting Started
### Prerequisite
@@ -22,7 +20,7 @@ make -C ..
```
You need to set up your provider.
See [setup guide](../docs/setup.md) for more.
See the [setup guide](../docs/setup.md) for more.
You need to install the following tools:
@@ -44,7 +42,6 @@ For example, you can create a cluster with Google account authentication.
```sh
make OIDC_ISSUER_URL=https://accounts.google.com \
OIDC_CLIENT_ID=REDACTED.apps.googleusercontent.com \
OIDC_CLIENT_SECRET=REDACTED \
YOUR_EMAIL=REDACTED@gmail.com
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 KiB

View File

@@ -10,178 +10,47 @@ Let's see the following steps:
1. Set up the kubeconfig
1. Verify cluster access
## 1. Set up the OIDC provider
### Google Identity Platform
Kubelogin supports the authentication flows such as Device Authorization Grant or Authorization Code Flow.
For the details of flows supported in Kubelogin, see the [usage](usage.md).
For the details of your provider, ask the administrator of your provider.
You can log in with a Google account.
## 2. Authenticate with the OpenID Connect Provider
Open [Google APIs Console](https://console.developers.google.com/apis/credentials) and create an OAuth client with the following setting:
- Application Type: Other
Check the client ID and secret.
Replace the following variables in the later sections.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://accounts.google.com`
`YOUR_CLIENT_ID` | `xxx.apps.googleusercontent.com`
`YOUR_CLIENT_SECRET` | random string
### Keycloak
You can log in with a user of Keycloak.
Make sure you have an administrator role of the Keycloak realm.
Open Keycloak and create an OIDC client as follows:
- Client ID: `YOUR_CLIENT_ID`
- Valid Redirect URLs:
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- Issuer URL: `https://keycloak.example.com/auth/realms/YOUR_REALM`
You can associate client roles by adding the following mapper:
- Name: `groups`
- Mapper Type: `User Client Role`
- Client ID: `YOUR_CLIENT_ID`
- Client Role prefix: `kubernetes:`
- Token Claim Name: `groups`
- Add to ID token: on
For example, if you have `admin` role of the client, you will get a JWT with the claim `{"groups": ["kubernetes:admin"]}`.
Replace the following variables in the later sections.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://keycloak.example.com/auth/realms/YOUR_REALM`
`YOUR_CLIENT_ID` | `YOUR_CLIENT_ID`
`YOUR_CLIENT_SECRET` | random string
### Dex with GitHub
You can log in with a GitHub account.
Open [GitHub OAuth Apps](https://github.com/settings/developers) and create an application with the following setting:
- Application name: (any)
- Homepage URL: `https://dex.example.com`
- Authorization callback URL: `https://dex.example.com/callback`
Deploy [Dex](https://github.com/dexidp/dex) with the following config:
```yaml
issuer: https://dex.example.com
connectors:
- type: github
id: github
name: GitHub
config:
clientID: YOUR_GITHUB_CLIENT_ID
clientSecret: YOUR_GITHUB_CLIENT_SECRET
redirectURI: https://dex.example.com/callback
staticClients:
- id: YOUR_CLIENT_ID
name: Kubernetes
redirectURIs:
- http://localhost:8000
- http://localhost:18000
secret: YOUR_DEX_CLIENT_SECRET
```
Replace the following variables in the later sections.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://dex.example.com`
`YOUR_CLIENT_ID` | `YOUR_CLIENT_ID`
`YOUR_CLIENT_SECRET` | `YOUR_DEX_CLIENT_SECRET`
### Okta
You can log in with an Okta user.
Okta supports [the authorization code flow with PKCE](https://developer.okta.com/docs/guides/implement-auth-code-pkce/overview/)
and this section explains how to set up it.
Open your Okta organization and create an application with the following options:
- Application type: Native
- Initiate login URI: `http://localhost:8000`
- Login redirect URIs:
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- Allowed grant types: Authorization Code
- Client authentication: Use PKCE (for public clients)
Replace the following variables in the later sections.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://YOUR_ORGANIZATION.okta.com`
`YOUR_CLIENT_ID` | random string
You do not need to set `YOUR_CLIENT_SECRET`.
If you need `groups` claim for access control,
see [jetstack/okta-kubectl-auth](https://github.com/jetstack/okta-kubectl-auth/blob/master/docs/okta-setup.md) and [#250](https://github.com/int128/kubelogin/issues/250).
### Ping Identity
Login with an account that has permissions to create applications.
Create an OIDC application with the following configuration:
- Redirect URIs:
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- Grant type: Authorization Code
- PKCE Enforcement: Required
Leverage the following variables in the next steps.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://auth.pingone.com/<PingOne Tenant Id>/as`
`YOUR_CLIENT_ID` | random string
`YOUR_CLIENT_SECRET` is not required for this configuration.
## 2. Verify authentication
Run the following command:
Run the following command to show the instruction to set up the configuration:
```sh
kubectl oidc-login setup \
--oidc-issuer-url=ISSUER_URL \
--oidc-client-id=YOUR_CLIENT_ID \
--oidc-client-secret=YOUR_CLIENT_SECRET
kubectl oidc-login setup --oidc-issuer-url=ISSUER_URL --oidc-client-id=YOUR_CLIENT_ID
```
It launches the browser and navigates to `http://localhost:8000`.
Please log in to the provider.
Set the following flags:
You can set extra options, for example, extra scope or CA certificate.
See also the full options.
- Set the issuer URL of your OpenID Connect provider to `--oidc-issuer-url`.
- Set the client ID for your OpenID Connect provider to `--oidc-client-id`.
- If your provider requires a client secret, set `--oidc-client-secret`.
If your provider supports the Device Authorization Grant, set `--grant-type=device-code`.
It launches the browser and navigates to the authentication page of your provider.
If your provider supports the Authorization Code Flow, set `--grant-type=authcode`.
It starts a local server for the authentication.
It launches the browser and navigates to the authentication page of your provider.
You can see the full options:
```sh
kubectl oidc-login setup --help
```
## 3. Bind a cluster role
Here bind `cluster-admin` role to you.
You can run the following command to bind `cluster-admin` role to you:
```sh
kubectl create clusterrolebinding oidc-cluster-admin --clusterrole=cluster-admin --user='ISSUER_URL#YOUR_SUBJECT'
```
As well as you can create a custom cluster role and bind it.
## 4. Set up the Kubernetes API server
Add the following flags to kube-apiserver:
@@ -193,40 +62,25 @@ Add the following flags to kube-apiserver:
See [Kubernetes Authenticating: OpenID Connect Tokens](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens) for the all flags.
If you are using [kops](https://github.com/kubernetes/kops), run `kops edit cluster` and append the following settings:
```yaml
spec:
kubeAPIServer:
oidcIssuerURL: ISSUER_URL
oidcClientID: YOUR_CLIENT_ID
```
If you are using [kube-aws](https://github.com/kubernetes-incubator/kube-aws), append the following settings to the `cluster.yaml`:
```yaml
oidc:
enabled: true
issuerUrl: ISSUER_URL
clientId: YOUR_CLIENT_ID
```
## 5. Set up the kubeconfig
Add `oidc` user to the kubeconfig.
```sh
kubectl config set-credentials oidc \
--exec-api-version=client.authentication.k8s.io/v1beta1 \
--exec-interactive-mode=Never \
--exec-api-version=client.authentication.k8s.io/v1 \
--exec-command=kubectl \
--exec-arg=oidc-login \
--exec-arg=get-token \
--exec-arg=--oidc-issuer-url=ISSUER_URL \
--exec-arg=--oidc-client-id=YOUR_CLIENT_ID \
--exec-arg=--oidc-client-secret=YOUR_CLIENT_SECRET
--exec-arg=--oidc-client-id=YOUR_CLIENT_ID
```
If your provider requires a client secret, add `--oidc-client-secret=YOUR_CLIENT_SECRET`.
For security, it is recommended to add `--token-cache-storage=keyring` to store the token cache to the keyring instead of the file system.
If you encounter an error, see the [token cache](usage.md#token-cache) for details.
## 6. Verify cluster access

View File

@@ -3,7 +3,6 @@
Kubelogin supports the standalone mode as well.
It writes the token to the kubeconfig (typically `~/.kube/config`) after authentication.
## Getting started
Configure your kubeconfig like:
@@ -53,16 +52,16 @@ Your kubeconfig looks like:
```yaml
users:
- name: keycloak
user:
auth-provider:
config:
client-id: YOUR_CLIENT_ID
client-secret: YOUR_CLIENT_SECRET
idp-issuer-url: https://issuer.example.com
id-token: ey... # kubelogin will add or update the ID token here
refresh-token: ey... # kubelogin will add or update the refresh token here
name: oidc
- name: keycloak
user:
auth-provider:
config:
client-id: YOUR_CLIENT_ID
client-secret: YOUR_CLIENT_SECRET
idp-issuer-url: https://issuer.example.com
id-token: ey... # kubelogin will add or update the ID token here
refresh-token: ey... # kubelogin will add or update the refresh token here
name: oidc
```
If the ID token is valid, kubelogin does nothing.
@@ -75,7 +74,6 @@ You already have a valid token until 2019-05-18 10:28:51 +0900 JST
If the ID token has expired, kubelogin will refresh the token using the refresh token in the kubeconfig.
If the refresh token has expired, kubelogin will proceed the authentication.
## Usage
You can set path to the kubeconfig file by the option or the environment variable just like kubectl.
@@ -94,15 +92,15 @@ If you set multiple files, kubelogin will find the file which has the current au
Kubelogin supports the following keys of `auth-provider` in a kubeconfig.
See [kubectl authentication](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-kubectl) for more.
Key | Direction | Value
----|-----------|------
`idp-issuer-url` | Read (Mandatory) | Issuer URL of the provider.
`client-id` | Read (Mandatory) | Client ID of the provider.
`client-secret` | Read (Mandatory) | Client Secret of the provider.
`idp-certificate-authority` | Read | CA certificate path of the provider.
`idp-certificate-authority-data` | Read | Base64 encoded CA certificate of the provider.
`extra-scopes` | Read | Scopes to request to the provider (comma separated).
`id-token` | Write | ID token got from the provider.
`refresh-token` | Write | Refresh token got from the provider.
| Key | Direction | Value |
| -------------------------------- | ---------------- | ---------------------------------------------------- |
| `idp-issuer-url` | Read (Mandatory) | Issuer URL of the provider. |
| `client-id` | Read (Mandatory) | Client ID of the provider. |
| `client-secret` | Read (Mandatory) | Client Secret of the provider. |
| `idp-certificate-authority` | Read | CA certificate path of the provider. |
| `idp-certificate-authority-data` | Read | Base64 encoded CA certificate of the provider. |
| `extra-scopes` | Read | Scopes to request to the provider (comma separated). |
| `id-token` | Write | ID token got from the provider. |
| `refresh-token` | Write | Refresh token got from the provider. |
See also [usage.md](usage.md).

View File

@@ -10,17 +10,20 @@ Flags:
--oidc-issuer-url string Issuer URL of the provider (mandatory)
--oidc-client-id string Client ID of the provider (mandatory)
--oidc-client-secret string Client secret of the provider
--oidc-redirect-url string [authcode, authcode-keyboard] Redirect URL
--oidc-extra-scope strings Scopes to request to the provider
--oidc-use-pkce Force PKCE usage
--oidc-use-access-token Instead of using the id_token, use the access_token to authenticate to Kubernetes
--token-cache-dir string Path to a directory for token cache (default "~/.kube/cache/oidc-login")
--oidc-request-header stringToString HTTP headers to send with an authentication request (default [])
--force-refresh If set, refresh the ID token regardless of its expiration time
--token-cache-dir string Path to a directory of the token cache (default "~/.kube/cache/oidc-login")
--token-cache-storage string Storage for the token cache. One of (disk|keyring|none) (default "disk")
--certificate-authority stringArray Path to a cert file for the certificate authority
--certificate-authority-data stringArray Base64 encoded cert for the certificate authority
--insecure-skip-tls-verify If set, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--insecure-skip-tls-verify [SECURITY RISK] If set, the server's certificate will not be checked for validity
--tls-renegotiation-once If set, allow a remote server to request renegotiation once per connection
--tls-renegotiation-freely If set, allow a remote server to repeatedly request renegotiation
--grant-type string Authorization grant type to use. One of (auto|authcode|authcode-keyboard|password|device-code) (default "auto")
--oidc-pkce-method string PKCE code challenge method. Automatically determined by default. One of (auto|no|S256) (default "auto")
--grant-type string Authorization grant type to use. One of (auto|authcode|authcode-keyboard|password|device-code|client-credentials) (default "auto")
--listen-address strings [authcode] Address to bind to the local server. If multiple addresses are set, it will try binding in order (default [127.0.0.1:8000,127.0.0.1:18000])
--skip-open-browser [authcode] Do not open the browser automatically
--browser-command string [authcode] Command to open the browser
@@ -28,9 +31,7 @@ Flags:
--local-server-cert string [authcode] Certificate path for the local server
--local-server-key string [authcode] Certificate key path for the local server
--open-url-after-authentication string [authcode] If set, open the URL in the browser after authentication
--oidc-redirect-url-hostname string [authcode] Hostname of the redirect URL (default "localhost")
--oidc-redirect-url-authcode-keyboard string [authcode-keyboard] Redirect URL (default "urn:ietf:wg:oauth:2.0:oob")
--oidc-auth-request-extra-params stringToString [authcode, authcode-keyboard] Extra query parameters to send with an authentication request (default [])
--oidc-auth-request-extra-params stringToString [authcode, authcode-keyboard, client-credentials] Extra query parameters to send with an authentication request (default [])
--username string [password] Username for resource owner password credentials grant
--password string [password] Password for resource owner password credentials grant
-h, --help help for get-token
@@ -51,7 +52,6 @@ Global Flags:
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
```
## Options
### Authentication timeout
@@ -61,7 +61,7 @@ This prevents a process from remaining forever.
You can change the timeout by the following flag:
```yaml
- --authentication-timeout-sec=60
- --authentication-timeout-sec=60
```
For now this timeout works only for the authorization code flow.
@@ -71,8 +71,32 @@ For now this timeout works only for the authorization code flow.
You can set the extra scopes to request to the provider by `--oidc-extra-scope`.
```yaml
- --oidc-extra-scope=email
- --oidc-extra-scope=profile
- --oidc-extra-scope=email
- --oidc-extra-scope=profile
```
### PKCE
Kubelogin automatically uses the PKCE if the provider supports it.
It determines the code challenge method by the `code_challenge_methods_supported` claim of the OpenID Connect Discovery document.
If your provider does not return a valid `code_challenge_methods_supported` claim,
you can enforce the code challenge method by `--oidc-pkce-method`.
```yaml
- --oidc-pkce-method=S256
```
For the most providers, you don't need to set this option explicitly.
### HTTP headers
If your provider requires extra HTTP headers, you can set them by `--oidc-request-header`.
For Azure AD Single Page Application with PKCE, you can set `Origin` header as follows:
```yaml
- --oidc-request-header=Origin=localhost
```
### CA certificate
@@ -80,8 +104,8 @@ You can set the extra scopes to request to the provider by `--oidc-extra-scope`.
You can use your self-signed certificate for the provider.
```yaml
- --certificate-authority=/home/user/.kube/keycloak-ca.pem
- --certificate-authority-data=LS0t...
- --certificate-authority=/home/user/.kube/keycloak-ca.pem
- --certificate-authority-data=LS0t...
```
### HTTP proxy
@@ -89,6 +113,27 @@ You can use your self-signed certificate for the provider.
You can set the following environment variables if you are behind a proxy: `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY`.
See also [net/http#ProxyFromEnvironment](https://golang.org/pkg/net/http/#ProxyFromEnvironment).
### Token cache
Kubelogin stores the token cache to the file system by default.
You can store the token cache to the OS keyring for enhanced security.
It depends on [zalando/go-keyring](https://github.com/zalando/go-keyring).
```yaml
- --token-cache-storage=keyring
```
You can delete the token cache by the clean command.
```console
% kubectl oidc-login clean
Deleted the token cache at /home/user/.kube/cache/oidc-login
Deleted the token cache from the keyring
```
For systems with immutable storage and no keyring, a cache type of none is available.
### Home directory expansion
If a value in the following options begins with a tilde character `~`, it is expanded to the home directory.
@@ -98,18 +143,40 @@ If a value in the following options begins with a tilde character `~`, it is exp
- `--local-server-key`
- `--token-cache-dir`
## Authentication flows
Kubelogin support the following flows:
- Authorization code flow
- Authorization code flow with a keyboard
- Resource owner password credentials grant flow
- [Device Authorization Grant](#device-authorization-grant)
- [Authorization Code Flow](#authorization-code-flow)
- [Authorization Code Flow with a Keyboard](#authorization-code-flow-with-a-keyboard)
- [Resource Owner Password Credentials Grant](#resource-owner-password-credentials-grant)
- [Client Credentials Flow](#client-credentials-flow)
### Authorization code flow
### Device Authorization Grant
Kubelogin performs the authorization code flow by default.
It performs the [Device Authorization Grant (RFC 8628)](https://tools.ietf.org/html/rfc8628) when `--grant-type=device-code` is set.
```yaml
- --grant-type=device-code
```
It automatically opens the browser.
If the provider returns the `verification_uri_complete` parameter, you don't need to enter the code.
Otherwise, you need to enter the code shown.
If you encounter a problem with the browser, you can change the browser command or skip opening the browser.
```yaml
# Change the browser command
- --browser-command=google-chrome
# Do not open the browser
- --skip-open-browser
```
### Authorization Code Flow
It performs the [Authorization Code Flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth) when `--grant-type=authcode` is set or the flag is not given.
It starts the local server at port 8000 or 18000 by default.
You need to register the following redirect URIs to the provider:
@@ -120,50 +187,60 @@ You need to register the following redirect URIs to the provider:
You can change the listening address.
```yaml
- --listen-address=127.0.0.1:12345
- --listen-address=127.0.0.1:23456
- --listen-address=127.0.0.1:12345
- --listen-address=127.0.0.1:23456
```
The redirect URL defaults to `http://localhost` with the listening port.
You can override the redirect URL.
```yaml
- --oidc-redirect-url=http://127.0.0.1:8000/
- --oidc-redirect-url=http://your-local-hostname:8000/
```
You can specify a certificate for the local webserver if HTTPS is required by your identity provider.
```yaml
- --local-server-cert=localhost.crt
- --local-server-key=localhost.key
```
You can change the hostname of redirect URI from the default value `localhost`.
```yaml
- --oidc-redirect-url-hostname=127.0.0.1
- --local-server-cert=localhost.crt
- --local-server-key=localhost.key
```
You can add extra parameters to the authentication request.
```yaml
- --oidc-auth-request-extra-params=ttl=86400
- --oidc-auth-request-extra-params=ttl=86400
```
When authentication completed, kubelogin shows a message to close the browser.
You can change the URL to show after authentication.
```yaml
- --open-url-after-authentication=https://example.com/success.html
- --open-url-after-authentication=https://example.com/success.html
```
You can skip opening the browser if you encounter some environment problem.
If you encounter a problem with the browser, you can change the browser command or skip opening the browser.
```yaml
- --skip-open-browser
# Change the browser command
- --browser-command=google-chrome
# Do not open the browser
- --skip-open-browser
```
For Linux users, you change the default browser by `BROWSER` environment variable.
### Authorization code flow with a keyboard
### Authorization Code Flow with a keyboard
If you cannot access the browser, instead use the authorization code flow with a keyboard.
```yaml
- --grant-type=authcode-keyboard
- --grant-type=authcode-keyboard
```
You need to explicitly set the redirect URL.
```yaml
- --oidc-redirect-url=urn:ietf:wg:oauth:2.0:oob
- --oidc-redirect-url=http://localhost
```
Kubelogin will show the URL and prompt.
@@ -175,38 +252,31 @@ Open https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&client_id=
Enter code: YOUR_CODE
```
The default of redirect URI is `urn:ietf:wg:oauth:2.0:oob`.
You can overwrite it.
```yaml
- oidc-redirect-url-authcode-keyboard=http://localhost
```
You can add extra parameters to the authentication request.
```yaml
- --oidc-auth-request-extra-params=ttl=86400
- --oidc-auth-request-extra-params=ttl=86400
```
### Resource owner password credentials grant flow
### Resource Owner Password Credentials Grant
Kubelogin performs the resource owner password credentials grant flow
It performs the [Resource Owner Password Credentials Grant](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3)
when `--grant-type=password` or `--username` is set.
Note that most OIDC providers do not support this flow.
Keycloak supports this flow but you need to explicitly enable the "Direct Access Grants" feature in the client settings.
Note that most OIDC providers do not support this grant.
Keycloak supports this grant but you need to explicitly enable the "Direct Access Grants" feature in the client settings.
You can set the username and password.
```yaml
- --username=USERNAME
- --password=PASSWORD
- --username=USERNAME
- --password=PASSWORD
```
If the password is not set, kubelogin will show the prompt for the password.
```yaml
- --username=USERNAME
- --username=USERNAME
```
```
@@ -217,7 +287,7 @@ Password:
If the username is not set, kubelogin will show the prompt for the username and password.
```yaml
- --grant-type=password
- --grant-type=password
```
```
@@ -226,6 +296,16 @@ Username: foo
Password:
```
### Client Credentials Flow
It performs the [OAuth 2.0 Client Credentials Flow](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.4) when `--grant-type=client-credentials` is set.
```yaml
- --grant-type=client-credentials
```
Per specification, this flow only returns authorization tokens.
## Run in Docker
You can run [the Docker image](https://ghcr.io/int128/kubelogin) instead of the binary.
@@ -233,25 +313,25 @@ The kubeconfig looks like:
```yaml
users:
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: docker
args:
- run
- --rm
- -v
- /tmp/.token-cache:/.token-cache
- -p
- 8000:8000
- ghcr.io/int128/kubelogin
- get-token
- --token-cache-dir=/.token-cache
- --listen-address=0.0.0.0:8000
- --oidc-issuer-url=ISSUER_URL
- --oidc-client-id=YOUR_CLIENT_ID
- --oidc-client-secret=YOUR_CLIENT_SECRET
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: docker
args:
- run
- --rm
- -v
- /tmp/.token-cache:/.token-cache
- -p
- 8000:8000
- ghcr.io/int128/kubelogin
- get-token
- --token-cache-dir=/.token-cache
- --listen-address=0.0.0.0:8000
- --oidc-issuer-url=ISSUER_URL
- --oidc-client-id=YOUR_CLIENT_ID
- --oidc-client-secret=YOUR_CLIENT_SECRET
```
Known limitations:

270
go.mod
View File

@@ -1,62 +1,274 @@
module github.com/int128/kubelogin
go 1.23.4
go 1.24.5
require (
github.com/chromedp/chromedp v0.11.2
github.com/coreos/go-oidc/v3 v3.12.0
github.com/chromedp/chromedp v0.13.7
github.com/coreos/go-oidc/v3 v3.14.1
github.com/gofrs/flock v0.12.1
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/go-cmp v0.6.0
github.com/golang-jwt/jwt/v5 v5.2.2
github.com/google/go-cmp v0.7.0
github.com/google/wire v0.6.0
github.com/int128/oauth2cli v1.14.1
github.com/int128/oauth2dev v1.0.1
github.com/int128/oauth2cli v1.17.0
github.com/int128/oauth2dev v1.1.0
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0
golang.org/x/oauth2 v0.25.0
golang.org/x/sync v0.10.0
golang.org/x/term v0.28.0
github.com/zalando/go-keyring v0.2.6
golang.org/x/oauth2 v0.30.0
golang.org/x/sync v0.16.0
golang.org/x/term v0.33.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/apimachinery v0.32.0
k8s.io/client-go v0.32.0
k8s.io/apimachinery v0.33.2
k8s.io/client-go v0.33.2
k8s.io/klog/v2 v2.130.1
)
require (
github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb // indirect
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
4d63.com/gochecknoglobals v0.2.2 // indirect
al.essio.dev/pkg/shellescape v1.5.1 // indirect
codeberg.org/chavacava/garif v0.2.0 // indirect
github.com/4meepo/tagalign v1.4.2 // indirect
github.com/Abirdcfly/dupword v0.1.6 // indirect
github.com/AlwxSin/noinlineerr v1.0.4 // indirect
github.com/Antonboom/errname v1.1.0 // indirect
github.com/Antonboom/nilnil v1.1.0 // indirect
github.com/Antonboom/testifylint v1.6.1 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 // indirect
github.com/Masterminds/semver/v3 v3.3.1 // indirect
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect
github.com/alecthomas/chroma/v2 v2.19.0 // indirect
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
github.com/alexkohler/nakedret/v2 v2.0.6 // indirect
github.com/alexkohler/prealloc v1.0.0 // indirect
github.com/alingse/asasalint v0.0.11 // indirect
github.com/alingse/nilnesserr v0.2.0 // indirect
github.com/ashanbrown/forbidigo/v2 v2.1.0 // indirect
github.com/ashanbrown/makezero/v2 v2.0.1 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bkielbasa/cyclop v1.2.3 // indirect
github.com/blizzy78/varnamelen v0.8.0 // indirect
github.com/bombsimon/wsl/v4 v4.7.0 // indirect
github.com/bombsimon/wsl/v5 v5.0.0 // indirect
github.com/breml/bidichk v0.3.3 // indirect
github.com/breml/errchkjson v0.4.1 // indirect
github.com/brunoga/deep v1.2.4 // indirect
github.com/butuzov/ireturn v0.4.0 // indirect
github.com/butuzov/mirror v1.3.0 // indirect
github.com/catenacyber/perfsprint v0.9.1 // indirect
github.com/ccojocar/zxcvbn-go v1.0.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charithe/durationcheck v0.0.10 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/ansi v0.8.0 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/chromedp/cdproto v0.0.0-20250403032234-65de8f5d025b // indirect
github.com/chromedp/sysutil v1.1.0 // indirect
github.com/ckaznocha/intrange v0.3.1 // indirect
github.com/curioswitch/go-reassign v0.3.0 // indirect
github.com/daixiang0/gci v0.13.6 // indirect
github.com/danieljoos/wincred v1.2.2 // indirect
github.com/dave/dst v0.27.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/denis-tingaikin/go-header v0.5.0 // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/ettle/strcase v0.2.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/firefart/nonamedreturns v1.0.6 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/ghostiam/protogetter v0.3.15 // indirect
github.com/go-critic/go-critic v0.13.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
github.com/go-json-experiment/json v0.0.0-20250211171154-1ae217ad3535 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
github.com/go-toolsmith/astcopy v1.1.0 // indirect
github.com/go-toolsmith/astequal v1.2.0 // indirect
github.com/go-toolsmith/astfmt v1.1.0 // indirect
github.com/go-toolsmith/astp v1.1.0 // indirect
github.com/go-toolsmith/strparse v1.1.0 // indirect
github.com/go-toolsmith/typep v1.1.0 // indirect
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.4.0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
github.com/golangci/go-printf-func-name v0.1.0 // indirect
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
github.com/golangci/golangci-lint/v2 v2.2.2 // indirect
github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95 // indirect
github.com/golangci/misspell v0.7.0 // indirect
github.com/golangci/plugin-module-register v0.1.2 // indirect
github.com/golangci/revgrep v0.8.0 // indirect
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
github.com/google/subcommands v1.2.0 // indirect
github.com/gordonklaus/ineffassign v0.1.0 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.5.0 // indirect
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/int128/listener v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/int128/listener v1.2.0 // indirect
github.com/jedib0t/go-pretty/v6 v6.6.7 // indirect
github.com/jgautheron/goconst v1.8.2 // indirect
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
github.com/jjti/go-spancheck v0.6.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/julz/importas v0.2.0 // indirect
github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect
github.com/kisielk/errcheck v1.9.0 // indirect
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/parsers/yaml v0.1.0 // indirect
github.com/knadh/koanf/providers/env v1.0.0 // indirect
github.com/knadh/koanf/providers/file v1.1.2 // indirect
github.com/knadh/koanf/providers/posflag v0.1.0 // indirect
github.com/knadh/koanf/providers/structs v0.1.0 // indirect
github.com/knadh/koanf/v2 v2.2.1 // indirect
github.com/kulti/thelper v0.6.3 // indirect
github.com/kunwardeep/paralleltest v1.0.14 // indirect
github.com/lasiar/canonicalheader v1.1.2 // indirect
github.com/ldez/exptostd v0.4.4 // indirect
github.com/ldez/gomoddirectives v0.7.0 // indirect
github.com/ldez/grignotin v0.9.0 // indirect
github.com/ldez/tagliatelle v0.7.1 // indirect
github.com/ldez/usetesting v0.5.0 // indirect
github.com/leonklingele/grouper v1.1.2 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/macabu/inamedparam v0.2.0 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/manuelarte/embeddedstructfieldcheck v0.3.0 // indirect
github.com/manuelarte/funcorder v0.5.0 // indirect
github.com/maratori/testableexamples v1.0.0 // indirect
github.com/maratori/testpackage v1.1.1 // indirect
github.com/matoous/godox v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mgechev/revive v1.10.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/moricho/tparallel v0.3.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/nishanths/exhaustive v0.12.0 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
github.com/nunnatsa/ginkgolinter v0.19.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/polyfloyd/go-errorlint v1.8.0 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/quasilyte/go-ruleguard v0.4.4 // indirect
github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect
github.com/quasilyte/gogrep v0.5.0 // indirect
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/raeperd/recvcheck v0.2.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/rs/zerolog v1.33.0 // indirect
github.com/ryancurrah/gomodguard v1.4.1 // indirect
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
github.com/securego/gosec/v2 v2.22.5 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sivchari/containedctx v1.0.3 // indirect
github.com/sonatard/noctx v0.3.4 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/sourcegraph/go-diff v0.7.0 // indirect
github.com/spf13/afero v1.14.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/viper v1.20.0 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tdakkota/asciicheck v0.4.1 // indirect
github.com/tetafro/godot v1.5.1 // indirect
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect
github.com/timonwong/loggercheck v0.11.0 // indirect
github.com/tomarrell/wrapcheck/v2 v2.11.0 // indirect
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/ultraware/funlen v0.2.0 // indirect
github.com/ultraware/whitespace v0.2.0 // indirect
github.com/uudashr/gocognit v1.2.0 // indirect
github.com/uudashr/iface v1.4.0 // indirect
github.com/vektra/mockery/v3 v3.5.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.7.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xen0n/gosmopolitan v1.3.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/yagipy/maintidx v1.0.0 // indirect
github.com/yeya24/promlinter v0.3.0 // indirect
github.com/ykadowak/zerologlint v0.1.5 // indirect
gitlab.com/bosi/decorder v0.4.2 // indirect
go-simpler.org/musttag v0.13.1 // indirect
go-simpler.org/sloglint v0.11.0 // indirect
go.augendre.info/arangolint v0.2.0 // indirect
go.augendre.info/fatcontext v0.8.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac // indirect
golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect
golang.org/x/mod v0.26.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.34.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
honnef.co/go/tools v0.6.1 // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
mvdan.cc/gofumpt v0.8.0 // indirect
mvdan.cc/unparam v0.0.0-20250301125049-0df0534333a4 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
tool (
github.com/golangci/golangci-lint/v2/cmd/golangci-lint
github.com/google/wire/cmd/wire
github.com/vektra/mockery/v3
)

1047
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
package integration_test
import (
"context"
"os"
"testing"
"time"
"github.com/int128/kubelogin/integration_test/httpdriver"
"github.com/int128/kubelogin/pkg/di"
"github.com/int128/kubelogin/pkg/testing/clock"
"github.com/int128/kubelogin/pkg/testing/logger"
)
func TestClean(t *testing.T) {
tokenCacheDir := t.TempDir()
cmd := di.NewCmdForHeadless(clock.Fake(time.Now()), os.Stdin, os.Stdout, logger.New(t), httpdriver.Zero(t))
exitCode := cmd.Run(context.TODO(), []string{
"kubelogin",
"clean",
"--token-cache-dir", tokenCacheDir,
}, "HEAD")
if exitCode != 0 {
t.Errorf("exit status wants 0 but %d", exitCode)
}
}

View File

@@ -19,7 +19,7 @@ import (
"github.com/int128/kubelogin/pkg/testing/clock"
"github.com/int128/kubelogin/pkg/testing/logger"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
clientauthenticationv1 "k8s.io/client-go/pkg/apis/clientauthentication/v1"
)
// Run the integration tests of the credential plugin use-case.
@@ -43,42 +43,42 @@ func TestCredentialPlugin(t *testing.T) {
args: []string{"--certificate-authority", keypair.Server.CACertPath},
},
} {
httpDriverOption := httpdriver.Option{
httpDriverConfig := httpdriver.Config{
TLSConfig: tc.keyPair.TLSConfig,
BodyContains: "Authenticated",
}
t.Run(name, func(t *testing.T) {
t.Run("AuthCode", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, testconfig.TestConfig{
svc := oidcserver.New(t, tc.keyPair, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverOption),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverConfig),
now: now,
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("ROPC", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, testconfig.TestConfig{
svc := oidcserver.New(t, tc.keyPair, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -86,13 +86,14 @@ func TestCredentialPlugin(t *testing.T) {
Password: "PASS1",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.Zero(t),
now: now,
stdout: &stdout,
@@ -101,104 +102,159 @@ func TestCredentialPlugin(t *testing.T) {
"--password", "PASS1",
}, tc.args...),
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("TokenCacheLifecycle", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, testconfig.TestConfig{})
svc := oidcserver.New(t, tc.keyPair, testconfig.Config{})
t.Run("NoCache", func(t *testing.T) {
sv.SetConfig(testconfig.TestConfig{
svc.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
RefreshToken: "REFRESH_TOKEN_1",
IDTokenExpiry: now.Add(time.Hour),
RefreshToken: "REFRESH_TOKEN_1",
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverOption),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverConfig),
now: now,
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("Valid", func(t *testing.T) {
sv.SetConfig(testconfig.TestConfig{})
svc.SetConfig(testconfig.Config{})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.Zero(t),
now: now,
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("Refresh", func(t *testing.T) {
sv.SetConfig(testconfig.TestConfig{
svc.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
RefreshToken: "REFRESH_TOKEN_1",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(3 * time.Hour),
RefreshToken: "REFRESH_TOKEN_2",
IDTokenExpiry: now.Add(3 * time.Hour),
RefreshToken: "REFRESH_TOKEN_2",
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverOption),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverConfig),
now: now.Add(2 * time.Hour),
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(3*time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(3*time.Hour))
})
t.Run("RefreshAgain", func(t *testing.T) {
sv.SetConfig(testconfig.TestConfig{
svc.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
RefreshToken: "REFRESH_TOKEN_2",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(5 * time.Hour),
IDTokenExpiry: now.Add(5 * time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverOption),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverConfig),
now: now.Add(4 * time.Hour),
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(5*time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(5*time.Hour))
})
})
})
}
t.Run("PKCE", func(t *testing.T) {
t.Parallel()
t.Run("Not supported by provider", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: nil,
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
})
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("Enforce", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: nil,
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{"--oidc-use-pkce"},
})
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
})
t.Run("TLSData", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, testconfig.TestConfig{
svc := oidcserver.New(t, keypair.Server, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -212,57 +268,34 @@ func TestCredentialPlugin(t *testing.T) {
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("TLSData", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.Server, testconfig.TestConfig{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{TLSConfig: keypair.Server.TLSConfig, BodyContains: "Authenticated"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{TLSConfig: keypair.Server.TLSConfig, BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{"--certificate-authority-data", keypair.Server.CACertBase64},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("ExtraScopes", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, testconfig.TestConfig{
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "email profile openid",
RedirectURIPrefix: "http://localhost:",
Scope: "email profile openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "Authenticated"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{
@@ -270,77 +303,80 @@ func TestCredentialPlugin(t *testing.T) {
"--oidc-extra-scope", "profile",
},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("OpenURLAfterAuthentication", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, testconfig.TestConfig{
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "URL=https://example.com/success"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "URL=https://example.com/success"}),
now: now,
stdout: &stdout,
args: []string{"--open-url-after-authentication", "https://example.com/success"},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("RedirectURLHostname", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, testconfig.TestConfig{
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://127.0.0.1:",
Scope: "openid",
RedirectURIPrefix: "http://127.0.0.1:",
CodeChallengeMethod: "S256",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "Authenticated"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{"--oidc-redirect-url-hostname", "127.0.0.1"},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("RedirectURLHTTPS", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, testconfig.TestConfig{
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "https://localhost:",
Scope: "openid",
RedirectURIPrefix: "https://localhost:",
CodeChallengeMethod: "S256",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{
TLSConfig: keypair.Server.TLSConfig,
BodyContains: "Authenticated",
}),
@@ -351,31 +387,32 @@ func TestCredentialPlugin(t *testing.T) {
"--local-server-key", keypair.Server.KeyPath,
},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("ExtraParams", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, testconfig.TestConfig{
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
ExtraParams: map[string]string{
"ttl": "86400",
"reauth": "false",
},
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "Authenticated"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{
@@ -383,7 +420,7 @@ func TestCredentialPlugin(t *testing.T) {
"--oidc-auth-request-extra-params", "reauth=false",
},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
}
@@ -398,6 +435,10 @@ type getTokenConfig struct {
func runGetToken(t *testing.T, ctx context.Context, cfg getTokenConfig) {
cmd := di.NewCmdForHeadless(clock.Fake(cfg.now), os.Stdin, cfg.stdout, logger.New(t), cfg.httpDriver)
t.Setenv(
"KUBERNETES_EXEC_INFO",
`{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1","spec":{"interactive":true}}`,
)
exitCode := cmd.Run(ctx, append([]string{
"kubelogin",
"get-token",
@@ -412,22 +453,22 @@ func runGetToken(t *testing.T, ctx context.Context, cfg getTokenConfig) {
}
func assertCredentialPluginStdout(t *testing.T, stdout io.Reader, token string, expiry time.Time) {
var got clientauthenticationv1beta1.ExecCredential
var got clientauthenticationv1.ExecCredential
if err := json.NewDecoder(stdout).Decode(&got); err != nil {
t.Errorf("could not decode json of the credential plugin: %s", err)
return
}
want := clientauthenticationv1beta1.ExecCredential{
want := clientauthenticationv1.ExecCredential{
TypeMeta: metav1.TypeMeta{
APIVersion: "client.authentication.k8s.io/v1beta1",
APIVersion: "client.authentication.k8s.io/v1",
Kind: "ExecCredential",
},
Status: &clientauthenticationv1beta1.ExecCredentialStatus{
Status: &clientauthenticationv1.ExecCredentialStatus{
Token: token,
ExpirationTimestamp: &metav1.Time{Time: expiry},
},
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("kubeconfig mismatch (-want +got):\n%s", diff)
t.Errorf("stdout mismatch (-want +got):\n%s", diff)
}
}

View File

@@ -10,14 +10,14 @@ import (
"testing"
)
type Option struct {
type Config struct {
TLSConfig *tls.Config
BodyContains string
}
// New returns a client to simulate browser access.
func New(ctx context.Context, t *testing.T, o Option) *client {
return &client{ctx, t, o}
func New(ctx context.Context, t *testing.T, config Config) *client {
return &client{ctx, t, config}
}
// Zero returns a client which call is not expected.
@@ -26,13 +26,13 @@ func Zero(t *testing.T) *zeroClient {
}
type client struct {
ctx context.Context
t *testing.T
o Option
ctx context.Context
t *testing.T
config Config
}
func (c *client) Open(url string) error {
client := http.Client{Transport: &http.Transport{TLSClientConfig: c.o.TLSConfig}}
client := http.Client{Transport: &http.Transport{TLSClientConfig: c.config.TLSConfig}}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
c.t.Errorf("could not create a request: %s", err)
@@ -44,7 +44,11 @@ func (c *client) Open(url string) error {
c.t.Errorf("could not send a request: %s", err)
return nil
}
defer resp.Body.Close()
defer func() {
if err := resp.Body.Close(); err != nil {
c.t.Errorf("could not close response body: %s", err)
}
}()
if resp.StatusCode != 200 {
c.t.Errorf("StatusCode wants 200 but %d", resp.StatusCode)
}
@@ -54,8 +58,8 @@ func (c *client) Open(url string) error {
return nil
}
body := string(b)
if !strings.Contains(body, c.o.BodyContains) {
c.t.Errorf("body should contain %s but was %s", c.o.BodyContains, body)
if !strings.Contains(body, c.config.BodyContains) {
c.t.Errorf("body should contain %s but was %s", c.config.BodyContains, body)
}
return nil
}

View File

@@ -36,7 +36,11 @@ func readAsBase64(name string) string {
if err != nil {
panic(err)
}
defer f.Close()
defer func() {
if err := f.Close(); err != nil {
panic(err)
}
}()
var s strings.Builder
e := base64.NewEncoder(base64.StdEncoding, &s)
if _, err := io.Copy(e, f); err != nil {

View File

@@ -27,7 +27,11 @@ func Create(t *testing.T, v *Values) string {
if err != nil {
t.Fatal(err)
}
defer f.Close()
defer func() {
if err := f.Close(); err != nil {
t.Fatal(err)
}
}()
tpl, err := template.ParseFiles("kubeconfig/testdata/kubeconfig.yaml")
if err != nil {
t.Fatal(err)
@@ -51,7 +55,11 @@ func Verify(t *testing.T, kubeconfig string, want AuthProviderConfig) {
t.Errorf("could not open kubeconfig: %s", err)
return
}
defer f.Close()
defer func() {
if err := f.Close(); err != nil {
t.Errorf("could not close kubeconfig: %s", err)
}
}()
var y struct {
Users []struct {

View File

@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net/http"
"net/url"
"testing"
"github.com/int128/kubelogin/integration_test/oidcserver/service"
@@ -28,10 +29,8 @@ type Handlers struct {
}
func (h *Handlers) handleError(w http.ResponseWriter, r *http.Request, f func() error) {
wr := &responseWriterRecorder{w, 200}
err := f()
if err == nil {
h.t.Logf("%d %s %s", wr.statusCode, r.Method, r.RequestURI)
return
}
if errResp := new(service.ErrorResponse); errors.As(err, &errResp) {
@@ -48,16 +47,6 @@ func (h *Handlers) handleError(w http.ResponseWriter, r *http.Request, f func()
http.Error(w, err.Error(), 500)
}
type responseWriterRecorder struct {
http.ResponseWriter
statusCode int
}
func (w *responseWriterRecorder) WriteHeader(statusCode int) {
w.ResponseWriter.WriteHeader(statusCode)
w.statusCode = statusCode
}
func (h *Handlers) Discovery(w http.ResponseWriter, r *http.Request) {
h.handleError(w, r, func() error {
discoveryResponse := h.provider.Discovery()
@@ -98,8 +87,12 @@ func (h *Handlers) AuthenticateCode(w http.ResponseWriter, r *http.Request) {
if err != nil {
return fmt.Errorf("authentication error: %w", err)
}
to := fmt.Sprintf("%s?state=%s&code=%s", redirectURI, state, code)
http.Redirect(w, r, to, 302)
redirectTo, err := url.Parse(redirectURI)
if err != nil {
return fmt.Errorf("invalid redirect_uri: %w", err)
}
redirectTo.RawQuery = url.Values{"state": {state}, "code": {code}}.Encode()
http.Redirect(w, r, redirectTo.String(), http.StatusFound)
return nil
})
}

View File

@@ -17,20 +17,20 @@ import (
)
// New starts a server for the OpenID Connect provider.
func New(t *testing.T, k keypair.KeyPair, c testconfig.TestConfig) service.Service {
func New(t *testing.T, kp keypair.KeyPair, config testconfig.Config) service.Service {
mux := http.NewServeMux()
serverURL := startServer(t, mux, k)
serverURL := startServer(t, mux, kp)
svc := service.New(t, serverURL, c)
svc := service.New(t, serverURL, config)
handler.Register(t, mux, svc)
return svc
}
func startServer(t *testing.T, h http.Handler, k keypair.KeyPair) string {
if k == keypair.None {
sv := httptest.NewServer(h)
t.Cleanup(sv.Close)
return sv.URL
func startServer(t *testing.T, h http.Handler, kp keypair.KeyPair) string {
if kp == keypair.None {
srv := httptest.NewServer(h)
t.Cleanup(srv.Close)
return srv.URL
}
// Unfortunately, httptest package did not work with keypair.KeyPair.
@@ -38,15 +38,15 @@ func startServer(t *testing.T, h http.Handler, k keypair.KeyPair) string {
portAllocator := httptest.NewUnstartedServer(h)
t.Cleanup(portAllocator.Close)
serverURL := fmt.Sprintf("https://localhost:%d", portAllocator.Listener.Addr().(*net.TCPAddr).Port)
sv := &http.Server{Handler: h}
srv := &http.Server{Handler: h}
go func() {
err := sv.ServeTLS(portAllocator.Listener, k.CertPath, k.KeyPath)
err := srv.ServeTLS(portAllocator.Listener, kp.CertPath, kp.KeyPath)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
t.Error(err)
}
}()
t.Cleanup(func() {
if err := sv.Shutdown(context.TODO()); err != nil {
if err := srv.Shutdown(context.TODO()); err != nil {
t.Errorf("could not shutdown the server: %s", err)
}
})

View File

@@ -10,11 +10,12 @@ import (
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/google/go-cmp/cmp"
"github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
testingJWT "github.com/int128/kubelogin/pkg/testing/jwt"
)
func New(t *testing.T, issuerURL string, config testconfig.TestConfig) Service {
func New(t *testing.T, issuerURL string, config testconfig.Config) Service {
return &service{
config: config,
t: t,
@@ -23,7 +24,7 @@ func New(t *testing.T, issuerURL string, config testconfig.TestConfig) Service {
}
type service struct {
config testconfig.TestConfig
config testconfig.Config
t *testing.T
issuerURL string
lastAuthenticationRequest *AuthenticationRequest
@@ -34,7 +35,7 @@ func (svc *service) IssuerURL() string {
return svc.issuerURL
}
func (svc *service) SetConfig(cfg testconfig.TestConfig) {
func (svc *service) SetConfig(cfg testconfig.Config) {
svc.config = cfg
}
@@ -84,8 +85,8 @@ func (svc *service) AuthenticateCode(req AuthenticationRequest) (code string, er
if !strings.HasPrefix(req.RedirectURI, svc.config.Want.RedirectURIPrefix) {
svc.t.Errorf("redirectURI wants prefix `%s` but was `%s`", svc.config.Want.RedirectURIPrefix, req.RedirectURI)
}
if req.CodeChallengeMethod != svc.config.Want.CodeChallengeMethod {
svc.t.Errorf("code_challenge_method wants `%s` but was `%s`", svc.config.Want.CodeChallengeMethod, req.CodeChallengeMethod)
if diff := cmp.Diff(svc.config.Want.CodeChallengeMethod, req.CodeChallengeMethod); diff != "" {
svc.t.Errorf("code_challenge_method mismatch (-want +got):\n%s", diff)
}
for k, v := range svc.config.Want.ExtraParams {
got := req.RawQuery.Get(k)

View File

@@ -13,7 +13,7 @@ type Service interface {
Provider
IssuerURL() string
SetConfig(config testconfig.TestConfig)
SetConfig(config testconfig.Config)
LastTokenResponse() *TokenResponse
}

View File

@@ -6,7 +6,7 @@ import "time"
type Want struct {
Scope string
RedirectURIPrefix string
CodeChallengeMethod string // optional
CodeChallengeMethod string
ExtraParams map[string]string // optional
Username string // optional
Password string // optional
@@ -17,12 +17,12 @@ type Want struct {
type Response struct {
IDTokenExpiry time.Time
RefreshToken string
RefreshError string // if set, Refresh() will return the error
CodeChallengeMethodsSupported []string // optional
RefreshError string // if set, Refresh() will return the error
CodeChallengeMethodsSupported []string
}
// TestConfig represents a configuration of the OpenID Connect provider.
type TestConfig struct {
// Config represents a configuration of the OpenID Connect provider.
type Config struct {
Want Want
Response Response
}

View File

@@ -36,7 +36,7 @@ func TestStandalone(t *testing.T) {
keyPair: keypair.Server,
},
} {
httpDriverOption := httpdriver.Option{
httpDriverOption := httpdriver.Config{
TLSConfig: tc.keyPair.TLSConfig,
BodyContains: "Authenticated",
}
@@ -46,7 +46,7 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, testconfig.TestConfig{
sv := oidcserver.New(t, tc.keyPair, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -75,7 +75,7 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, testconfig.TestConfig{
sv := oidcserver.New(t, tc.keyPair, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -110,14 +110,14 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, testconfig.TestConfig{})
sv := oidcserver.New(t, tc.keyPair, testconfig.Config{})
kubeConfigFilename := kubeconfig.Create(t, &kubeconfig.Values{
Issuer: sv.IssuerURL(),
IDPCertificateAuthority: tc.keyPair.CACertPath,
})
t.Run("NoToken", func(t *testing.T) {
sv.SetConfig(testconfig.TestConfig{
sv.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -139,7 +139,7 @@ func TestStandalone(t *testing.T) {
})
})
t.Run("Valid", func(t *testing.T) {
sv.SetConfig(testconfig.TestConfig{})
sv.SetConfig(testconfig.Config{})
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
kubeConfigFilename: kubeConfigFilename,
@@ -152,7 +152,7 @@ func TestStandalone(t *testing.T) {
})
})
t.Run("Refresh", func(t *testing.T) {
sv.SetConfig(testconfig.TestConfig{
sv.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -175,7 +175,7 @@ func TestStandalone(t *testing.T) {
})
})
t.Run("RefreshAgain", func(t *testing.T) {
sv.SetConfig(testconfig.TestConfig{
sv.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -204,7 +204,7 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.Server, testconfig.TestConfig{
sv := oidcserver.New(t, keypair.Server, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -220,7 +220,7 @@ func TestStandalone(t *testing.T) {
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
kubeConfigFilename: kubeConfigFilename,
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{TLSConfig: keypair.Server.TLSConfig}),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{TLSConfig: keypair.Server.TLSConfig}),
now: now,
})
kubeconfig.Verify(t, kubeConfigFilename, kubeconfig.AuthProviderConfig{
@@ -232,7 +232,7 @@ func TestStandalone(t *testing.T) {
t.Run("env_KUBECONFIG", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, testconfig.TestConfig{
sv := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
@@ -247,7 +247,7 @@ func TestStandalone(t *testing.T) {
t.Setenv("KUBECONFIG", kubeConfigFilename+string(os.PathListSeparator)+"kubeconfig/testdata/dummy.yaml")
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{}),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{}),
now: now,
})
kubeconfig.Verify(t, kubeConfigFilename, kubeconfig.AuthProviderConfig{
@@ -260,7 +260,7 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, testconfig.TestConfig{
sv := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "profile groups openid",
RedirectURIPrefix: "http://localhost:",
@@ -276,7 +276,7 @@ func TestStandalone(t *testing.T) {
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
kubeConfigFilename: kubeConfigFilename,
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{}),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{}),
now: now,
})
kubeconfig.Verify(t, kubeConfigFilename, kubeconfig.AuthProviderConfig{

View File

@@ -1,361 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package service_mock
import (
service "github.com/int128/kubelogin/integration_test/oidcserver/service"
mock "github.com/stretchr/testify/mock"
)
// MockProvider is an autogenerated mock type for the Provider type
type MockProvider struct {
mock.Mock
}
type MockProvider_Expecter struct {
mock *mock.Mock
}
func (_m *MockProvider) EXPECT() *MockProvider_Expecter {
return &MockProvider_Expecter{mock: &_m.Mock}
}
// AuthenticateCode provides a mock function with given fields: req
func (_m *MockProvider) AuthenticateCode(req service.AuthenticationRequest) (string, error) {
ret := _m.Called(req)
if len(ret) == 0 {
panic("no return value specified for AuthenticateCode")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(service.AuthenticationRequest) (string, error)); ok {
return rf(req)
}
if rf, ok := ret.Get(0).(func(service.AuthenticationRequest) string); ok {
r0 = rf(req)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(service.AuthenticationRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_AuthenticateCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticateCode'
type MockProvider_AuthenticateCode_Call struct {
*mock.Call
}
// AuthenticateCode is a helper method to define mock.On call
// - req service.AuthenticationRequest
func (_e *MockProvider_Expecter) AuthenticateCode(req interface{}) *MockProvider_AuthenticateCode_Call {
return &MockProvider_AuthenticateCode_Call{Call: _e.mock.On("AuthenticateCode", req)}
}
func (_c *MockProvider_AuthenticateCode_Call) Run(run func(req service.AuthenticationRequest)) *MockProvider_AuthenticateCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(service.AuthenticationRequest))
})
return _c
}
func (_c *MockProvider_AuthenticateCode_Call) Return(code string, err error) *MockProvider_AuthenticateCode_Call {
_c.Call.Return(code, err)
return _c
}
func (_c *MockProvider_AuthenticateCode_Call) RunAndReturn(run func(service.AuthenticationRequest) (string, error)) *MockProvider_AuthenticateCode_Call {
_c.Call.Return(run)
return _c
}
// AuthenticatePassword provides a mock function with given fields: username, password, scope
func (_m *MockProvider) AuthenticatePassword(username string, password string, scope string) (*service.TokenResponse, error) {
ret := _m.Called(username, password, scope)
if len(ret) == 0 {
panic("no return value specified for AuthenticatePassword")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(string, string, string) (*service.TokenResponse, error)); ok {
return rf(username, password, scope)
}
if rf, ok := ret.Get(0).(func(string, string, string) *service.TokenResponse); ok {
r0 = rf(username, password, scope)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(username, password, scope)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_AuthenticatePassword_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticatePassword'
type MockProvider_AuthenticatePassword_Call struct {
*mock.Call
}
// AuthenticatePassword is a helper method to define mock.On call
// - username string
// - password string
// - scope string
func (_e *MockProvider_Expecter) AuthenticatePassword(username interface{}, password interface{}, scope interface{}) *MockProvider_AuthenticatePassword_Call {
return &MockProvider_AuthenticatePassword_Call{Call: _e.mock.On("AuthenticatePassword", username, password, scope)}
}
func (_c *MockProvider_AuthenticatePassword_Call) Run(run func(username string, password string, scope string)) *MockProvider_AuthenticatePassword_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockProvider_AuthenticatePassword_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockProvider_AuthenticatePassword_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockProvider_AuthenticatePassword_Call) RunAndReturn(run func(string, string, string) (*service.TokenResponse, error)) *MockProvider_AuthenticatePassword_Call {
_c.Call.Return(run)
return _c
}
// Discovery provides a mock function with no fields
func (_m *MockProvider) Discovery() *service.DiscoveryResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Discovery")
}
var r0 *service.DiscoveryResponse
if rf, ok := ret.Get(0).(func() *service.DiscoveryResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.DiscoveryResponse)
}
}
return r0
}
// MockProvider_Discovery_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Discovery'
type MockProvider_Discovery_Call struct {
*mock.Call
}
// Discovery is a helper method to define mock.On call
func (_e *MockProvider_Expecter) Discovery() *MockProvider_Discovery_Call {
return &MockProvider_Discovery_Call{Call: _e.mock.On("Discovery")}
}
func (_c *MockProvider_Discovery_Call) Run(run func()) *MockProvider_Discovery_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockProvider_Discovery_Call) Return(_a0 *service.DiscoveryResponse) *MockProvider_Discovery_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockProvider_Discovery_Call) RunAndReturn(run func() *service.DiscoveryResponse) *MockProvider_Discovery_Call {
_c.Call.Return(run)
return _c
}
// Exchange provides a mock function with given fields: req
func (_m *MockProvider) Exchange(req service.TokenRequest) (*service.TokenResponse, error) {
ret := _m.Called(req)
if len(ret) == 0 {
panic("no return value specified for Exchange")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(service.TokenRequest) (*service.TokenResponse, error)); ok {
return rf(req)
}
if rf, ok := ret.Get(0).(func(service.TokenRequest) *service.TokenResponse); ok {
r0 = rf(req)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(service.TokenRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_Exchange_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Exchange'
type MockProvider_Exchange_Call struct {
*mock.Call
}
// Exchange is a helper method to define mock.On call
// - req service.TokenRequest
func (_e *MockProvider_Expecter) Exchange(req interface{}) *MockProvider_Exchange_Call {
return &MockProvider_Exchange_Call{Call: _e.mock.On("Exchange", req)}
}
func (_c *MockProvider_Exchange_Call) Run(run func(req service.TokenRequest)) *MockProvider_Exchange_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(service.TokenRequest))
})
return _c
}
func (_c *MockProvider_Exchange_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockProvider_Exchange_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockProvider_Exchange_Call) RunAndReturn(run func(service.TokenRequest) (*service.TokenResponse, error)) *MockProvider_Exchange_Call {
_c.Call.Return(run)
return _c
}
// GetCertificates provides a mock function with no fields
func (_m *MockProvider) GetCertificates() *service.CertificatesResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for GetCertificates")
}
var r0 *service.CertificatesResponse
if rf, ok := ret.Get(0).(func() *service.CertificatesResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.CertificatesResponse)
}
}
return r0
}
// MockProvider_GetCertificates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCertificates'
type MockProvider_GetCertificates_Call struct {
*mock.Call
}
// GetCertificates is a helper method to define mock.On call
func (_e *MockProvider_Expecter) GetCertificates() *MockProvider_GetCertificates_Call {
return &MockProvider_GetCertificates_Call{Call: _e.mock.On("GetCertificates")}
}
func (_c *MockProvider_GetCertificates_Call) Run(run func()) *MockProvider_GetCertificates_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockProvider_GetCertificates_Call) Return(_a0 *service.CertificatesResponse) *MockProvider_GetCertificates_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockProvider_GetCertificates_Call) RunAndReturn(run func() *service.CertificatesResponse) *MockProvider_GetCertificates_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function with given fields: refreshToken
func (_m *MockProvider) Refresh(refreshToken string) (*service.TokenResponse, error) {
ret := _m.Called(refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(string) (*service.TokenResponse, error)); ok {
return rf(refreshToken)
}
if rf, ok := ret.Get(0).(func(string) *service.TokenResponse); ok {
r0 = rf(refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockProvider_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - refreshToken string
func (_e *MockProvider_Expecter) Refresh(refreshToken interface{}) *MockProvider_Refresh_Call {
return &MockProvider_Refresh_Call{Call: _e.mock.On("Refresh", refreshToken)}
}
func (_c *MockProvider_Refresh_Call) Run(run func(refreshToken string)) *MockProvider_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockProvider_Refresh_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockProvider_Refresh_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockProvider_Refresh_Call) RunAndReturn(run func(string) (*service.TokenResponse, error)) *MockProvider_Refresh_Call {
_c.Call.Return(run)
return _c
}
// NewMockProvider creates a new instance of MockProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockProvider(t interface {
mock.TestingT
Cleanup(func())
}) *MockProvider {
mock := &MockProvider{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,487 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package service_mock
import (
service "github.com/int128/kubelogin/integration_test/oidcserver/service"
testconfig "github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
mock "github.com/stretchr/testify/mock"
)
// MockService is an autogenerated mock type for the Service type
type MockService struct {
mock.Mock
}
type MockService_Expecter struct {
mock *mock.Mock
}
func (_m *MockService) EXPECT() *MockService_Expecter {
return &MockService_Expecter{mock: &_m.Mock}
}
// AuthenticateCode provides a mock function with given fields: req
func (_m *MockService) AuthenticateCode(req service.AuthenticationRequest) (string, error) {
ret := _m.Called(req)
if len(ret) == 0 {
panic("no return value specified for AuthenticateCode")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(service.AuthenticationRequest) (string, error)); ok {
return rf(req)
}
if rf, ok := ret.Get(0).(func(service.AuthenticationRequest) string); ok {
r0 = rf(req)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(service.AuthenticationRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_AuthenticateCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticateCode'
type MockService_AuthenticateCode_Call struct {
*mock.Call
}
// AuthenticateCode is a helper method to define mock.On call
// - req service.AuthenticationRequest
func (_e *MockService_Expecter) AuthenticateCode(req interface{}) *MockService_AuthenticateCode_Call {
return &MockService_AuthenticateCode_Call{Call: _e.mock.On("AuthenticateCode", req)}
}
func (_c *MockService_AuthenticateCode_Call) Run(run func(req service.AuthenticationRequest)) *MockService_AuthenticateCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(service.AuthenticationRequest))
})
return _c
}
func (_c *MockService_AuthenticateCode_Call) Return(code string, err error) *MockService_AuthenticateCode_Call {
_c.Call.Return(code, err)
return _c
}
func (_c *MockService_AuthenticateCode_Call) RunAndReturn(run func(service.AuthenticationRequest) (string, error)) *MockService_AuthenticateCode_Call {
_c.Call.Return(run)
return _c
}
// AuthenticatePassword provides a mock function with given fields: username, password, scope
func (_m *MockService) AuthenticatePassword(username string, password string, scope string) (*service.TokenResponse, error) {
ret := _m.Called(username, password, scope)
if len(ret) == 0 {
panic("no return value specified for AuthenticatePassword")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(string, string, string) (*service.TokenResponse, error)); ok {
return rf(username, password, scope)
}
if rf, ok := ret.Get(0).(func(string, string, string) *service.TokenResponse); ok {
r0 = rf(username, password, scope)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(username, password, scope)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_AuthenticatePassword_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticatePassword'
type MockService_AuthenticatePassword_Call struct {
*mock.Call
}
// AuthenticatePassword is a helper method to define mock.On call
// - username string
// - password string
// - scope string
func (_e *MockService_Expecter) AuthenticatePassword(username interface{}, password interface{}, scope interface{}) *MockService_AuthenticatePassword_Call {
return &MockService_AuthenticatePassword_Call{Call: _e.mock.On("AuthenticatePassword", username, password, scope)}
}
func (_c *MockService_AuthenticatePassword_Call) Run(run func(username string, password string, scope string)) *MockService_AuthenticatePassword_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockService_AuthenticatePassword_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockService_AuthenticatePassword_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_AuthenticatePassword_Call) RunAndReturn(run func(string, string, string) (*service.TokenResponse, error)) *MockService_AuthenticatePassword_Call {
_c.Call.Return(run)
return _c
}
// Discovery provides a mock function with no fields
func (_m *MockService) Discovery() *service.DiscoveryResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Discovery")
}
var r0 *service.DiscoveryResponse
if rf, ok := ret.Get(0).(func() *service.DiscoveryResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.DiscoveryResponse)
}
}
return r0
}
// MockService_Discovery_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Discovery'
type MockService_Discovery_Call struct {
*mock.Call
}
// Discovery is a helper method to define mock.On call
func (_e *MockService_Expecter) Discovery() *MockService_Discovery_Call {
return &MockService_Discovery_Call{Call: _e.mock.On("Discovery")}
}
func (_c *MockService_Discovery_Call) Run(run func()) *MockService_Discovery_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_Discovery_Call) Return(_a0 *service.DiscoveryResponse) *MockService_Discovery_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_Discovery_Call) RunAndReturn(run func() *service.DiscoveryResponse) *MockService_Discovery_Call {
_c.Call.Return(run)
return _c
}
// Exchange provides a mock function with given fields: req
func (_m *MockService) Exchange(req service.TokenRequest) (*service.TokenResponse, error) {
ret := _m.Called(req)
if len(ret) == 0 {
panic("no return value specified for Exchange")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(service.TokenRequest) (*service.TokenResponse, error)); ok {
return rf(req)
}
if rf, ok := ret.Get(0).(func(service.TokenRequest) *service.TokenResponse); ok {
r0 = rf(req)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(service.TokenRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_Exchange_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Exchange'
type MockService_Exchange_Call struct {
*mock.Call
}
// Exchange is a helper method to define mock.On call
// - req service.TokenRequest
func (_e *MockService_Expecter) Exchange(req interface{}) *MockService_Exchange_Call {
return &MockService_Exchange_Call{Call: _e.mock.On("Exchange", req)}
}
func (_c *MockService_Exchange_Call) Run(run func(req service.TokenRequest)) *MockService_Exchange_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(service.TokenRequest))
})
return _c
}
func (_c *MockService_Exchange_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockService_Exchange_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_Exchange_Call) RunAndReturn(run func(service.TokenRequest) (*service.TokenResponse, error)) *MockService_Exchange_Call {
_c.Call.Return(run)
return _c
}
// GetCertificates provides a mock function with no fields
func (_m *MockService) GetCertificates() *service.CertificatesResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for GetCertificates")
}
var r0 *service.CertificatesResponse
if rf, ok := ret.Get(0).(func() *service.CertificatesResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.CertificatesResponse)
}
}
return r0
}
// MockService_GetCertificates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCertificates'
type MockService_GetCertificates_Call struct {
*mock.Call
}
// GetCertificates is a helper method to define mock.On call
func (_e *MockService_Expecter) GetCertificates() *MockService_GetCertificates_Call {
return &MockService_GetCertificates_Call{Call: _e.mock.On("GetCertificates")}
}
func (_c *MockService_GetCertificates_Call) Run(run func()) *MockService_GetCertificates_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_GetCertificates_Call) Return(_a0 *service.CertificatesResponse) *MockService_GetCertificates_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_GetCertificates_Call) RunAndReturn(run func() *service.CertificatesResponse) *MockService_GetCertificates_Call {
_c.Call.Return(run)
return _c
}
// IssuerURL provides a mock function with no fields
func (_m *MockService) IssuerURL() string {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for IssuerURL")
}
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// MockService_IssuerURL_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IssuerURL'
type MockService_IssuerURL_Call struct {
*mock.Call
}
// IssuerURL is a helper method to define mock.On call
func (_e *MockService_Expecter) IssuerURL() *MockService_IssuerURL_Call {
return &MockService_IssuerURL_Call{Call: _e.mock.On("IssuerURL")}
}
func (_c *MockService_IssuerURL_Call) Run(run func()) *MockService_IssuerURL_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_IssuerURL_Call) Return(_a0 string) *MockService_IssuerURL_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_IssuerURL_Call) RunAndReturn(run func() string) *MockService_IssuerURL_Call {
_c.Call.Return(run)
return _c
}
// LastTokenResponse provides a mock function with no fields
func (_m *MockService) LastTokenResponse() *service.TokenResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for LastTokenResponse")
}
var r0 *service.TokenResponse
if rf, ok := ret.Get(0).(func() *service.TokenResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
return r0
}
// MockService_LastTokenResponse_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LastTokenResponse'
type MockService_LastTokenResponse_Call struct {
*mock.Call
}
// LastTokenResponse is a helper method to define mock.On call
func (_e *MockService_Expecter) LastTokenResponse() *MockService_LastTokenResponse_Call {
return &MockService_LastTokenResponse_Call{Call: _e.mock.On("LastTokenResponse")}
}
func (_c *MockService_LastTokenResponse_Call) Run(run func()) *MockService_LastTokenResponse_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_LastTokenResponse_Call) Return(_a0 *service.TokenResponse) *MockService_LastTokenResponse_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_LastTokenResponse_Call) RunAndReturn(run func() *service.TokenResponse) *MockService_LastTokenResponse_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function with given fields: refreshToken
func (_m *MockService) Refresh(refreshToken string) (*service.TokenResponse, error) {
ret := _m.Called(refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(string) (*service.TokenResponse, error)); ok {
return rf(refreshToken)
}
if rf, ok := ret.Get(0).(func(string) *service.TokenResponse); ok {
r0 = rf(refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockService_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - refreshToken string
func (_e *MockService_Expecter) Refresh(refreshToken interface{}) *MockService_Refresh_Call {
return &MockService_Refresh_Call{Call: _e.mock.On("Refresh", refreshToken)}
}
func (_c *MockService_Refresh_Call) Run(run func(refreshToken string)) *MockService_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockService_Refresh_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockService_Refresh_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_Refresh_Call) RunAndReturn(run func(string) (*service.TokenResponse, error)) *MockService_Refresh_Call {
_c.Call.Return(run)
return _c
}
// SetConfig provides a mock function with given fields: config
func (_m *MockService) SetConfig(config testconfig.TestConfig) {
_m.Called(config)
}
// MockService_SetConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetConfig'
type MockService_SetConfig_Call struct {
*mock.Call
}
// SetConfig is a helper method to define mock.On call
// - config testconfig.TestConfig
func (_e *MockService_Expecter) SetConfig(config interface{}) *MockService_SetConfig_Call {
return &MockService_SetConfig_Call{Call: _e.mock.On("SetConfig", config)}
}
func (_c *MockService_SetConfig_Call) Run(run func(config testconfig.TestConfig)) *MockService_SetConfig_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(testconfig.TestConfig))
})
return _c
}
func (_c *MockService_SetConfig_Call) Return() *MockService_SetConfig_Call {
_c.Call.Return()
return _c
}
func (_c *MockService_SetConfig_Call) RunAndReturn(run func(testconfig.TestConfig)) *MockService_SetConfig_Call {
_c.Run(run)
return _c
}
// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockService(t interface {
mock.TestingT
Cleanup(func())
}) *MockService {
mock := &MockService{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,895 @@
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package service_mock
import (
"github.com/int128/kubelogin/integration_test/oidcserver/service"
"github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
mock "github.com/stretchr/testify/mock"
)
// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockService(t interface {
mock.TestingT
Cleanup(func())
}) *MockService {
mock := &MockService{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockService is an autogenerated mock type for the Service type
type MockService struct {
mock.Mock
}
type MockService_Expecter struct {
mock *mock.Mock
}
func (_m *MockService) EXPECT() *MockService_Expecter {
return &MockService_Expecter{mock: &_m.Mock}
}
// AuthenticateCode provides a mock function for the type MockService
func (_mock *MockService) AuthenticateCode(req service.AuthenticationRequest) (string, error) {
ret := _mock.Called(req)
if len(ret) == 0 {
panic("no return value specified for AuthenticateCode")
}
var r0 string
var r1 error
if returnFunc, ok := ret.Get(0).(func(service.AuthenticationRequest) (string, error)); ok {
return returnFunc(req)
}
if returnFunc, ok := ret.Get(0).(func(service.AuthenticationRequest) string); ok {
r0 = returnFunc(req)
} else {
r0 = ret.Get(0).(string)
}
if returnFunc, ok := ret.Get(1).(func(service.AuthenticationRequest) error); ok {
r1 = returnFunc(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_AuthenticateCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticateCode'
type MockService_AuthenticateCode_Call struct {
*mock.Call
}
// AuthenticateCode is a helper method to define mock.On call
// - req service.AuthenticationRequest
func (_e *MockService_Expecter) AuthenticateCode(req interface{}) *MockService_AuthenticateCode_Call {
return &MockService_AuthenticateCode_Call{Call: _e.mock.On("AuthenticateCode", req)}
}
func (_c *MockService_AuthenticateCode_Call) Run(run func(req service.AuthenticationRequest)) *MockService_AuthenticateCode_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 service.AuthenticationRequest
if args[0] != nil {
arg0 = args[0].(service.AuthenticationRequest)
}
run(
arg0,
)
})
return _c
}
func (_c *MockService_AuthenticateCode_Call) Return(code string, err error) *MockService_AuthenticateCode_Call {
_c.Call.Return(code, err)
return _c
}
func (_c *MockService_AuthenticateCode_Call) RunAndReturn(run func(req service.AuthenticationRequest) (string, error)) *MockService_AuthenticateCode_Call {
_c.Call.Return(run)
return _c
}
// AuthenticatePassword provides a mock function for the type MockService
func (_mock *MockService) AuthenticatePassword(username string, password string, scope string) (*service.TokenResponse, error) {
ret := _mock.Called(username, password, scope)
if len(ret) == 0 {
panic("no return value specified for AuthenticatePassword")
}
var r0 *service.TokenResponse
var r1 error
if returnFunc, ok := ret.Get(0).(func(string, string, string) (*service.TokenResponse, error)); ok {
return returnFunc(username, password, scope)
}
if returnFunc, ok := ret.Get(0).(func(string, string, string) *service.TokenResponse); ok {
r0 = returnFunc(username, password, scope)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if returnFunc, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = returnFunc(username, password, scope)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_AuthenticatePassword_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticatePassword'
type MockService_AuthenticatePassword_Call struct {
*mock.Call
}
// AuthenticatePassword is a helper method to define mock.On call
// - username string
// - password string
// - scope string
func (_e *MockService_Expecter) AuthenticatePassword(username interface{}, password interface{}, scope interface{}) *MockService_AuthenticatePassword_Call {
return &MockService_AuthenticatePassword_Call{Call: _e.mock.On("AuthenticatePassword", username, password, scope)}
}
func (_c *MockService_AuthenticatePassword_Call) Run(run func(username string, password string, scope string)) *MockService_AuthenticatePassword_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
var arg1 string
if args[1] != nil {
arg1 = args[1].(string)
}
var arg2 string
if args[2] != nil {
arg2 = args[2].(string)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockService_AuthenticatePassword_Call) Return(tokenResponse *service.TokenResponse, err error) *MockService_AuthenticatePassword_Call {
_c.Call.Return(tokenResponse, err)
return _c
}
func (_c *MockService_AuthenticatePassword_Call) RunAndReturn(run func(username string, password string, scope string) (*service.TokenResponse, error)) *MockService_AuthenticatePassword_Call {
_c.Call.Return(run)
return _c
}
// Discovery provides a mock function for the type MockService
func (_mock *MockService) Discovery() *service.DiscoveryResponse {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for Discovery")
}
var r0 *service.DiscoveryResponse
if returnFunc, ok := ret.Get(0).(func() *service.DiscoveryResponse); ok {
r0 = returnFunc()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.DiscoveryResponse)
}
}
return r0
}
// MockService_Discovery_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Discovery'
type MockService_Discovery_Call struct {
*mock.Call
}
// Discovery is a helper method to define mock.On call
func (_e *MockService_Expecter) Discovery() *MockService_Discovery_Call {
return &MockService_Discovery_Call{Call: _e.mock.On("Discovery")}
}
func (_c *MockService_Discovery_Call) Run(run func()) *MockService_Discovery_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_Discovery_Call) Return(discoveryResponse *service.DiscoveryResponse) *MockService_Discovery_Call {
_c.Call.Return(discoveryResponse)
return _c
}
func (_c *MockService_Discovery_Call) RunAndReturn(run func() *service.DiscoveryResponse) *MockService_Discovery_Call {
_c.Call.Return(run)
return _c
}
// Exchange provides a mock function for the type MockService
func (_mock *MockService) Exchange(req service.TokenRequest) (*service.TokenResponse, error) {
ret := _mock.Called(req)
if len(ret) == 0 {
panic("no return value specified for Exchange")
}
var r0 *service.TokenResponse
var r1 error
if returnFunc, ok := ret.Get(0).(func(service.TokenRequest) (*service.TokenResponse, error)); ok {
return returnFunc(req)
}
if returnFunc, ok := ret.Get(0).(func(service.TokenRequest) *service.TokenResponse); ok {
r0 = returnFunc(req)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if returnFunc, ok := ret.Get(1).(func(service.TokenRequest) error); ok {
r1 = returnFunc(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_Exchange_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Exchange'
type MockService_Exchange_Call struct {
*mock.Call
}
// Exchange is a helper method to define mock.On call
// - req service.TokenRequest
func (_e *MockService_Expecter) Exchange(req interface{}) *MockService_Exchange_Call {
return &MockService_Exchange_Call{Call: _e.mock.On("Exchange", req)}
}
func (_c *MockService_Exchange_Call) Run(run func(req service.TokenRequest)) *MockService_Exchange_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 service.TokenRequest
if args[0] != nil {
arg0 = args[0].(service.TokenRequest)
}
run(
arg0,
)
})
return _c
}
func (_c *MockService_Exchange_Call) Return(tokenResponse *service.TokenResponse, err error) *MockService_Exchange_Call {
_c.Call.Return(tokenResponse, err)
return _c
}
func (_c *MockService_Exchange_Call) RunAndReturn(run func(req service.TokenRequest) (*service.TokenResponse, error)) *MockService_Exchange_Call {
_c.Call.Return(run)
return _c
}
// GetCertificates provides a mock function for the type MockService
func (_mock *MockService) GetCertificates() *service.CertificatesResponse {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for GetCertificates")
}
var r0 *service.CertificatesResponse
if returnFunc, ok := ret.Get(0).(func() *service.CertificatesResponse); ok {
r0 = returnFunc()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.CertificatesResponse)
}
}
return r0
}
// MockService_GetCertificates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCertificates'
type MockService_GetCertificates_Call struct {
*mock.Call
}
// GetCertificates is a helper method to define mock.On call
func (_e *MockService_Expecter) GetCertificates() *MockService_GetCertificates_Call {
return &MockService_GetCertificates_Call{Call: _e.mock.On("GetCertificates")}
}
func (_c *MockService_GetCertificates_Call) Run(run func()) *MockService_GetCertificates_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_GetCertificates_Call) Return(certificatesResponse *service.CertificatesResponse) *MockService_GetCertificates_Call {
_c.Call.Return(certificatesResponse)
return _c
}
func (_c *MockService_GetCertificates_Call) RunAndReturn(run func() *service.CertificatesResponse) *MockService_GetCertificates_Call {
_c.Call.Return(run)
return _c
}
// IssuerURL provides a mock function for the type MockService
func (_mock *MockService) IssuerURL() string {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for IssuerURL")
}
var r0 string
if returnFunc, ok := ret.Get(0).(func() string); ok {
r0 = returnFunc()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// MockService_IssuerURL_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IssuerURL'
type MockService_IssuerURL_Call struct {
*mock.Call
}
// IssuerURL is a helper method to define mock.On call
func (_e *MockService_Expecter) IssuerURL() *MockService_IssuerURL_Call {
return &MockService_IssuerURL_Call{Call: _e.mock.On("IssuerURL")}
}
func (_c *MockService_IssuerURL_Call) Run(run func()) *MockService_IssuerURL_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_IssuerURL_Call) Return(s string) *MockService_IssuerURL_Call {
_c.Call.Return(s)
return _c
}
func (_c *MockService_IssuerURL_Call) RunAndReturn(run func() string) *MockService_IssuerURL_Call {
_c.Call.Return(run)
return _c
}
// LastTokenResponse provides a mock function for the type MockService
func (_mock *MockService) LastTokenResponse() *service.TokenResponse {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for LastTokenResponse")
}
var r0 *service.TokenResponse
if returnFunc, ok := ret.Get(0).(func() *service.TokenResponse); ok {
r0 = returnFunc()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
return r0
}
// MockService_LastTokenResponse_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LastTokenResponse'
type MockService_LastTokenResponse_Call struct {
*mock.Call
}
// LastTokenResponse is a helper method to define mock.On call
func (_e *MockService_Expecter) LastTokenResponse() *MockService_LastTokenResponse_Call {
return &MockService_LastTokenResponse_Call{Call: _e.mock.On("LastTokenResponse")}
}
func (_c *MockService_LastTokenResponse_Call) Run(run func()) *MockService_LastTokenResponse_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_LastTokenResponse_Call) Return(tokenResponse *service.TokenResponse) *MockService_LastTokenResponse_Call {
_c.Call.Return(tokenResponse)
return _c
}
func (_c *MockService_LastTokenResponse_Call) RunAndReturn(run func() *service.TokenResponse) *MockService_LastTokenResponse_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function for the type MockService
func (_mock *MockService) Refresh(refreshToken string) (*service.TokenResponse, error) {
ret := _mock.Called(refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *service.TokenResponse
var r1 error
if returnFunc, ok := ret.Get(0).(func(string) (*service.TokenResponse, error)); ok {
return returnFunc(refreshToken)
}
if returnFunc, ok := ret.Get(0).(func(string) *service.TokenResponse); ok {
r0 = returnFunc(refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if returnFunc, ok := ret.Get(1).(func(string) error); ok {
r1 = returnFunc(refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockService_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - refreshToken string
func (_e *MockService_Expecter) Refresh(refreshToken interface{}) *MockService_Refresh_Call {
return &MockService_Refresh_Call{Call: _e.mock.On("Refresh", refreshToken)}
}
func (_c *MockService_Refresh_Call) Run(run func(refreshToken string)) *MockService_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
run(
arg0,
)
})
return _c
}
func (_c *MockService_Refresh_Call) Return(tokenResponse *service.TokenResponse, err error) *MockService_Refresh_Call {
_c.Call.Return(tokenResponse, err)
return _c
}
func (_c *MockService_Refresh_Call) RunAndReturn(run func(refreshToken string) (*service.TokenResponse, error)) *MockService_Refresh_Call {
_c.Call.Return(run)
return _c
}
// SetConfig provides a mock function for the type MockService
func (_mock *MockService) SetConfig(config testconfig.Config) {
_mock.Called(config)
return
}
// MockService_SetConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetConfig'
type MockService_SetConfig_Call struct {
*mock.Call
}
// SetConfig is a helper method to define mock.On call
// - config testconfig.Config
func (_e *MockService_Expecter) SetConfig(config interface{}) *MockService_SetConfig_Call {
return &MockService_SetConfig_Call{Call: _e.mock.On("SetConfig", config)}
}
func (_c *MockService_SetConfig_Call) Run(run func(config testconfig.Config)) *MockService_SetConfig_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 testconfig.Config
if args[0] != nil {
arg0 = args[0].(testconfig.Config)
}
run(
arg0,
)
})
return _c
}
func (_c *MockService_SetConfig_Call) Return() *MockService_SetConfig_Call {
_c.Call.Return()
return _c
}
func (_c *MockService_SetConfig_Call) RunAndReturn(run func(config testconfig.Config)) *MockService_SetConfig_Call {
_c.Run(run)
return _c
}
// NewMockProvider creates a new instance of MockProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockProvider(t interface {
mock.TestingT
Cleanup(func())
}) *MockProvider {
mock := &MockProvider{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockProvider is an autogenerated mock type for the Provider type
type MockProvider struct {
mock.Mock
}
type MockProvider_Expecter struct {
mock *mock.Mock
}
func (_m *MockProvider) EXPECT() *MockProvider_Expecter {
return &MockProvider_Expecter{mock: &_m.Mock}
}
// AuthenticateCode provides a mock function for the type MockProvider
func (_mock *MockProvider) AuthenticateCode(req service.AuthenticationRequest) (string, error) {
ret := _mock.Called(req)
if len(ret) == 0 {
panic("no return value specified for AuthenticateCode")
}
var r0 string
var r1 error
if returnFunc, ok := ret.Get(0).(func(service.AuthenticationRequest) (string, error)); ok {
return returnFunc(req)
}
if returnFunc, ok := ret.Get(0).(func(service.AuthenticationRequest) string); ok {
r0 = returnFunc(req)
} else {
r0 = ret.Get(0).(string)
}
if returnFunc, ok := ret.Get(1).(func(service.AuthenticationRequest) error); ok {
r1 = returnFunc(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_AuthenticateCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticateCode'
type MockProvider_AuthenticateCode_Call struct {
*mock.Call
}
// AuthenticateCode is a helper method to define mock.On call
// - req service.AuthenticationRequest
func (_e *MockProvider_Expecter) AuthenticateCode(req interface{}) *MockProvider_AuthenticateCode_Call {
return &MockProvider_AuthenticateCode_Call{Call: _e.mock.On("AuthenticateCode", req)}
}
func (_c *MockProvider_AuthenticateCode_Call) Run(run func(req service.AuthenticationRequest)) *MockProvider_AuthenticateCode_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 service.AuthenticationRequest
if args[0] != nil {
arg0 = args[0].(service.AuthenticationRequest)
}
run(
arg0,
)
})
return _c
}
func (_c *MockProvider_AuthenticateCode_Call) Return(code string, err error) *MockProvider_AuthenticateCode_Call {
_c.Call.Return(code, err)
return _c
}
func (_c *MockProvider_AuthenticateCode_Call) RunAndReturn(run func(req service.AuthenticationRequest) (string, error)) *MockProvider_AuthenticateCode_Call {
_c.Call.Return(run)
return _c
}
// AuthenticatePassword provides a mock function for the type MockProvider
func (_mock *MockProvider) AuthenticatePassword(username string, password string, scope string) (*service.TokenResponse, error) {
ret := _mock.Called(username, password, scope)
if len(ret) == 0 {
panic("no return value specified for AuthenticatePassword")
}
var r0 *service.TokenResponse
var r1 error
if returnFunc, ok := ret.Get(0).(func(string, string, string) (*service.TokenResponse, error)); ok {
return returnFunc(username, password, scope)
}
if returnFunc, ok := ret.Get(0).(func(string, string, string) *service.TokenResponse); ok {
r0 = returnFunc(username, password, scope)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if returnFunc, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = returnFunc(username, password, scope)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_AuthenticatePassword_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticatePassword'
type MockProvider_AuthenticatePassword_Call struct {
*mock.Call
}
// AuthenticatePassword is a helper method to define mock.On call
// - username string
// - password string
// - scope string
func (_e *MockProvider_Expecter) AuthenticatePassword(username interface{}, password interface{}, scope interface{}) *MockProvider_AuthenticatePassword_Call {
return &MockProvider_AuthenticatePassword_Call{Call: _e.mock.On("AuthenticatePassword", username, password, scope)}
}
func (_c *MockProvider_AuthenticatePassword_Call) Run(run func(username string, password string, scope string)) *MockProvider_AuthenticatePassword_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
var arg1 string
if args[1] != nil {
arg1 = args[1].(string)
}
var arg2 string
if args[2] != nil {
arg2 = args[2].(string)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockProvider_AuthenticatePassword_Call) Return(tokenResponse *service.TokenResponse, err error) *MockProvider_AuthenticatePassword_Call {
_c.Call.Return(tokenResponse, err)
return _c
}
func (_c *MockProvider_AuthenticatePassword_Call) RunAndReturn(run func(username string, password string, scope string) (*service.TokenResponse, error)) *MockProvider_AuthenticatePassword_Call {
_c.Call.Return(run)
return _c
}
// Discovery provides a mock function for the type MockProvider
func (_mock *MockProvider) Discovery() *service.DiscoveryResponse {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for Discovery")
}
var r0 *service.DiscoveryResponse
if returnFunc, ok := ret.Get(0).(func() *service.DiscoveryResponse); ok {
r0 = returnFunc()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.DiscoveryResponse)
}
}
return r0
}
// MockProvider_Discovery_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Discovery'
type MockProvider_Discovery_Call struct {
*mock.Call
}
// Discovery is a helper method to define mock.On call
func (_e *MockProvider_Expecter) Discovery() *MockProvider_Discovery_Call {
return &MockProvider_Discovery_Call{Call: _e.mock.On("Discovery")}
}
func (_c *MockProvider_Discovery_Call) Run(run func()) *MockProvider_Discovery_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockProvider_Discovery_Call) Return(discoveryResponse *service.DiscoveryResponse) *MockProvider_Discovery_Call {
_c.Call.Return(discoveryResponse)
return _c
}
func (_c *MockProvider_Discovery_Call) RunAndReturn(run func() *service.DiscoveryResponse) *MockProvider_Discovery_Call {
_c.Call.Return(run)
return _c
}
// Exchange provides a mock function for the type MockProvider
func (_mock *MockProvider) Exchange(req service.TokenRequest) (*service.TokenResponse, error) {
ret := _mock.Called(req)
if len(ret) == 0 {
panic("no return value specified for Exchange")
}
var r0 *service.TokenResponse
var r1 error
if returnFunc, ok := ret.Get(0).(func(service.TokenRequest) (*service.TokenResponse, error)); ok {
return returnFunc(req)
}
if returnFunc, ok := ret.Get(0).(func(service.TokenRequest) *service.TokenResponse); ok {
r0 = returnFunc(req)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if returnFunc, ok := ret.Get(1).(func(service.TokenRequest) error); ok {
r1 = returnFunc(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_Exchange_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Exchange'
type MockProvider_Exchange_Call struct {
*mock.Call
}
// Exchange is a helper method to define mock.On call
// - req service.TokenRequest
func (_e *MockProvider_Expecter) Exchange(req interface{}) *MockProvider_Exchange_Call {
return &MockProvider_Exchange_Call{Call: _e.mock.On("Exchange", req)}
}
func (_c *MockProvider_Exchange_Call) Run(run func(req service.TokenRequest)) *MockProvider_Exchange_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 service.TokenRequest
if args[0] != nil {
arg0 = args[0].(service.TokenRequest)
}
run(
arg0,
)
})
return _c
}
func (_c *MockProvider_Exchange_Call) Return(tokenResponse *service.TokenResponse, err error) *MockProvider_Exchange_Call {
_c.Call.Return(tokenResponse, err)
return _c
}
func (_c *MockProvider_Exchange_Call) RunAndReturn(run func(req service.TokenRequest) (*service.TokenResponse, error)) *MockProvider_Exchange_Call {
_c.Call.Return(run)
return _c
}
// GetCertificates provides a mock function for the type MockProvider
func (_mock *MockProvider) GetCertificates() *service.CertificatesResponse {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for GetCertificates")
}
var r0 *service.CertificatesResponse
if returnFunc, ok := ret.Get(0).(func() *service.CertificatesResponse); ok {
r0 = returnFunc()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.CertificatesResponse)
}
}
return r0
}
// MockProvider_GetCertificates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCertificates'
type MockProvider_GetCertificates_Call struct {
*mock.Call
}
// GetCertificates is a helper method to define mock.On call
func (_e *MockProvider_Expecter) GetCertificates() *MockProvider_GetCertificates_Call {
return &MockProvider_GetCertificates_Call{Call: _e.mock.On("GetCertificates")}
}
func (_c *MockProvider_GetCertificates_Call) Run(run func()) *MockProvider_GetCertificates_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockProvider_GetCertificates_Call) Return(certificatesResponse *service.CertificatesResponse) *MockProvider_GetCertificates_Call {
_c.Call.Return(certificatesResponse)
return _c
}
func (_c *MockProvider_GetCertificates_Call) RunAndReturn(run func() *service.CertificatesResponse) *MockProvider_GetCertificates_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function for the type MockProvider
func (_mock *MockProvider) Refresh(refreshToken string) (*service.TokenResponse, error) {
ret := _mock.Called(refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *service.TokenResponse
var r1 error
if returnFunc, ok := ret.Get(0).(func(string) (*service.TokenResponse, error)); ok {
return returnFunc(refreshToken)
}
if returnFunc, ok := ret.Get(0).(func(string) *service.TokenResponse); ok {
r0 = returnFunc(refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if returnFunc, ok := ret.Get(1).(func(string) error); ok {
r1 = returnFunc(refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockProvider_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - refreshToken string
func (_e *MockProvider_Expecter) Refresh(refreshToken interface{}) *MockProvider_Refresh_Call {
return &MockProvider_Refresh_Call{Call: _e.mock.On("Refresh", refreshToken)}
}
func (_c *MockProvider_Refresh_Call) Run(run func(refreshToken string)) *MockProvider_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
run(
arg0,
)
})
return _c
}
func (_c *MockProvider_Refresh_Call) Return(tokenResponse *service.TokenResponse, err error) *MockProvider_Refresh_Call {
_c.Call.Return(tokenResponse, err)
return _c
}
func (_c *MockProvider_Refresh_Call) RunAndReturn(run func(refreshToken string) (*service.TokenResponse, error)) *MockProvider_Refresh_Call {
_c.Call.Return(run)
return _c
}

View File

@@ -1,13 +1,29 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package cmd_mock
import (
context "context"
"context"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -21,21 +37,20 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Run provides a mock function with given fields: ctx, args, version
func (_m *MockInterface) Run(ctx context.Context, args []string, version string) int {
ret := _m.Called(ctx, args, version)
// Run provides a mock function for the type MockInterface
func (_mock *MockInterface) Run(ctx context.Context, args []string, version string) int {
ret := _mock.Called(ctx, args, version)
if len(ret) == 0 {
panic("no return value specified for Run")
}
var r0 int
if rf, ok := ret.Get(0).(func(context.Context, []string, string) int); ok {
r0 = rf(ctx, args, version)
if returnFunc, ok := ret.Get(0).(func(context.Context, []string, string) int); ok {
r0 = returnFunc(ctx, args, version)
} else {
r0 = ret.Get(0).(int)
}
return r0
}
@@ -54,31 +69,33 @@ func (_e *MockInterface_Expecter) Run(ctx interface{}, args interface{}, version
func (_c *MockInterface_Run_Call) Run(run func(ctx context.Context, args []string, version string)) *MockInterface_Run_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].([]string), args[2].(string))
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 []string
if args[1] != nil {
arg1 = args[1].([]string)
}
var arg2 string
if args[2] != nil {
arg2 = args[2].(string)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockInterface_Run_Call) Return(_a0 int) *MockInterface_Run_Call {
_c.Call.Return(_a0)
func (_c *MockInterface_Run_Call) Return(n int) *MockInterface_Run_Call {
_c.Call.Return(n)
return _c
}
func (_c *MockInterface_Run_Call) RunAndReturn(run func(context.Context, []string, string) int) *MockInterface_Run_Call {
func (_c *MockInterface_Run_Call) RunAndReturn(run func(ctx context.Context, args []string, version string) int) *MockInterface_Run_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,12 +1,28 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package reader_mock
import (
credentialplugin "github.com/int128/kubelogin/pkg/credentialplugin"
"github.com/int128/kubelogin/pkg/credentialplugin"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -20,9 +36,9 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Read provides a mock function with no fields
func (_m *MockInterface) Read() (credentialplugin.Input, error) {
ret := _m.Called()
// Read provides a mock function for the type MockInterface
func (_mock *MockInterface) Read() (credentialplugin.Input, error) {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for Read")
@@ -30,21 +46,19 @@ func (_m *MockInterface) Read() (credentialplugin.Input, error) {
var r0 credentialplugin.Input
var r1 error
if rf, ok := ret.Get(0).(func() (credentialplugin.Input, error)); ok {
return rf()
if returnFunc, ok := ret.Get(0).(func() (credentialplugin.Input, error)); ok {
return returnFunc()
}
if rf, ok := ret.Get(0).(func() credentialplugin.Input); ok {
r0 = rf()
if returnFunc, ok := ret.Get(0).(func() credentialplugin.Input); ok {
r0 = returnFunc()
} else {
r0 = ret.Get(0).(credentialplugin.Input)
}
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
if returnFunc, ok := ret.Get(1).(func() error); ok {
r1 = returnFunc()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
@@ -65,8 +79,8 @@ func (_c *MockInterface_Read_Call) Run(run func()) *MockInterface_Read_Call {
return _c
}
func (_c *MockInterface_Read_Call) Return(_a0 credentialplugin.Input, _a1 error) *MockInterface_Read_Call {
_c.Call.Return(_a0, _a1)
func (_c *MockInterface_Read_Call) Return(input credentialplugin.Input, err error) *MockInterface_Read_Call {
_c.Call.Return(input, err)
return _c
}
@@ -74,17 +88,3 @@ func (_c *MockInterface_Read_Call) RunAndReturn(run func() (credentialplugin.Inp
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,12 +1,28 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package writer_mock
import (
credentialplugin "github.com/int128/kubelogin/pkg/credentialplugin"
"github.com/int128/kubelogin/pkg/credentialplugin"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -20,21 +36,20 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Write provides a mock function with given fields: out
func (_m *MockInterface) Write(out credentialplugin.Output) error {
ret := _m.Called(out)
// Write provides a mock function for the type MockInterface
func (_mock *MockInterface) Write(out credentialplugin.Output) error {
ret := _mock.Called(out)
if len(ret) == 0 {
panic("no return value specified for Write")
}
var r0 error
if rf, ok := ret.Get(0).(func(credentialplugin.Output) error); ok {
r0 = rf(out)
if returnFunc, ok := ret.Get(0).(func(credentialplugin.Output) error); ok {
r0 = returnFunc(out)
} else {
r0 = ret.Error(0)
}
return r0
}
@@ -51,31 +66,23 @@ func (_e *MockInterface_Expecter) Write(out interface{}) *MockInterface_Write_Ca
func (_c *MockInterface_Write_Call) Run(run func(out credentialplugin.Output)) *MockInterface_Write_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(credentialplugin.Output))
var arg0 credentialplugin.Output
if args[0] != nil {
arg0 = args[0].(credentialplugin.Output)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_Write_Call) Return(_a0 error) *MockInterface_Write_Call {
_c.Call.Return(_a0)
func (_c *MockInterface_Write_Call) Return(err error) *MockInterface_Write_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_Write_Call) RunAndReturn(run func(credentialplugin.Output) error) *MockInterface_Write_Call {
func (_c *MockInterface_Write_Call) RunAndReturn(run func(out credentialplugin.Output) error) *MockInterface_Write_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,13 +1,29 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package browser_mock
import (
context "context"
"context"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -21,21 +37,20 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Open provides a mock function with given fields: url
func (_m *MockInterface) Open(url string) error {
ret := _m.Called(url)
// Open provides a mock function for the type MockInterface
func (_mock *MockInterface) Open(url string) error {
ret := _mock.Called(url)
if len(ret) == 0 {
panic("no return value specified for Open")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(url)
if returnFunc, ok := ret.Get(0).(func(string) error); ok {
r0 = returnFunc(url)
} else {
r0 = ret.Error(0)
}
return r0
}
@@ -52,36 +67,41 @@ func (_e *MockInterface_Expecter) Open(url interface{}) *MockInterface_Open_Call
func (_c *MockInterface_Open_Call) Run(run func(url string)) *MockInterface_Open_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_Open_Call) Return(_a0 error) *MockInterface_Open_Call {
_c.Call.Return(_a0)
func (_c *MockInterface_Open_Call) Return(err error) *MockInterface_Open_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_Open_Call) RunAndReturn(run func(string) error) *MockInterface_Open_Call {
func (_c *MockInterface_Open_Call) RunAndReturn(run func(url string) error) *MockInterface_Open_Call {
_c.Call.Return(run)
return _c
}
// OpenCommand provides a mock function with given fields: ctx, url, command
func (_m *MockInterface) OpenCommand(ctx context.Context, url string, command string) error {
ret := _m.Called(ctx, url, command)
// OpenCommand provides a mock function for the type MockInterface
func (_mock *MockInterface) OpenCommand(ctx context.Context, url string, command string) error {
ret := _mock.Called(ctx, url, command)
if len(ret) == 0 {
panic("no return value specified for OpenCommand")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok {
r0 = rf(ctx, url, command)
if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) error); ok {
r0 = returnFunc(ctx, url, command)
} else {
r0 = ret.Error(0)
}
return r0
}
@@ -100,31 +120,33 @@ func (_e *MockInterface_Expecter) OpenCommand(ctx interface{}, url interface{},
func (_c *MockInterface_OpenCommand_Call) Run(run func(ctx context.Context, url string, command string)) *MockInterface_OpenCommand_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string))
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 string
if args[1] != nil {
arg1 = args[1].(string)
}
var arg2 string
if args[2] != nil {
arg2 = args[2].(string)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockInterface_OpenCommand_Call) Return(_a0 error) *MockInterface_OpenCommand_Call {
_c.Call.Return(_a0)
func (_c *MockInterface_OpenCommand_Call) Return(err error) *MockInterface_OpenCommand_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_OpenCommand_Call) RunAndReturn(run func(context.Context, string, string) error) *MockInterface_OpenCommand_Call {
func (_c *MockInterface_OpenCommand_Call) RunAndReturn(run func(ctx context.Context, url string, command string) error) *MockInterface_OpenCommand_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,13 +1,29 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package clock_mock
import (
time "time"
"time"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -21,21 +37,20 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Now provides a mock function with no fields
func (_m *MockInterface) Now() time.Time {
ret := _m.Called()
// Now provides a mock function for the type MockInterface
func (_mock *MockInterface) Now() time.Time {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for Now")
}
var r0 time.Time
if rf, ok := ret.Get(0).(func() time.Time); ok {
r0 = rf()
if returnFunc, ok := ret.Get(0).(func() time.Time); ok {
r0 = returnFunc()
} else {
r0 = ret.Get(0).(time.Time)
}
return r0
}
@@ -56,8 +71,8 @@ func (_c *MockInterface_Now_Call) Run(run func()) *MockInterface_Now_Call {
return _c
}
func (_c *MockInterface_Now_Call) Return(_a0 time.Time) *MockInterface_Now_Call {
_c.Call.Return(_a0)
func (_c *MockInterface_Now_Call) Return(time1 time.Time) *MockInterface_Now_Call {
_c.Call.Return(time1)
return _c
}
@@ -65,17 +80,3 @@ func (_c *MockInterface_Now_Call) RunAndReturn(run func() time.Time) *MockInterf
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,208 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package logger_mock
import (
logger "github.com/int128/kubelogin/pkg/infrastructure/logger"
mock "github.com/stretchr/testify/mock"
pflag "github.com/spf13/pflag"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// AddFlags provides a mock function with given fields: f
func (_m *MockInterface) AddFlags(f *pflag.FlagSet) {
_m.Called(f)
}
// MockInterface_AddFlags_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddFlags'
type MockInterface_AddFlags_Call struct {
*mock.Call
}
// AddFlags is a helper method to define mock.On call
// - f *pflag.FlagSet
func (_e *MockInterface_Expecter) AddFlags(f interface{}) *MockInterface_AddFlags_Call {
return &MockInterface_AddFlags_Call{Call: _e.mock.On("AddFlags", f)}
}
func (_c *MockInterface_AddFlags_Call) Run(run func(f *pflag.FlagSet)) *MockInterface_AddFlags_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*pflag.FlagSet))
})
return _c
}
func (_c *MockInterface_AddFlags_Call) Return() *MockInterface_AddFlags_Call {
_c.Call.Return()
return _c
}
func (_c *MockInterface_AddFlags_Call) RunAndReturn(run func(*pflag.FlagSet)) *MockInterface_AddFlags_Call {
_c.Run(run)
return _c
}
// IsEnabled provides a mock function with given fields: level
func (_m *MockInterface) IsEnabled(level int) bool {
ret := _m.Called(level)
if len(ret) == 0 {
panic("no return value specified for IsEnabled")
}
var r0 bool
if rf, ok := ret.Get(0).(func(int) bool); ok {
r0 = rf(level)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// MockInterface_IsEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsEnabled'
type MockInterface_IsEnabled_Call struct {
*mock.Call
}
// IsEnabled is a helper method to define mock.On call
// - level int
func (_e *MockInterface_Expecter) IsEnabled(level interface{}) *MockInterface_IsEnabled_Call {
return &MockInterface_IsEnabled_Call{Call: _e.mock.On("IsEnabled", level)}
}
func (_c *MockInterface_IsEnabled_Call) Run(run func(level int)) *MockInterface_IsEnabled_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(int))
})
return _c
}
func (_c *MockInterface_IsEnabled_Call) Return(_a0 bool) *MockInterface_IsEnabled_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_IsEnabled_Call) RunAndReturn(run func(int) bool) *MockInterface_IsEnabled_Call {
_c.Call.Return(run)
return _c
}
// Printf provides a mock function with given fields: format, args
func (_m *MockInterface) Printf(format string, args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, format)
_ca = append(_ca, args...)
_m.Called(_ca...)
}
// MockInterface_Printf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Printf'
type MockInterface_Printf_Call struct {
*mock.Call
}
// Printf is a helper method to define mock.On call
// - format string
// - args ...interface{}
func (_e *MockInterface_Expecter) Printf(format interface{}, args ...interface{}) *MockInterface_Printf_Call {
return &MockInterface_Printf_Call{Call: _e.mock.On("Printf",
append([]interface{}{format}, args...)...)}
}
func (_c *MockInterface_Printf_Call) Run(run func(format string, args ...interface{})) *MockInterface_Printf_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]interface{}, len(args)-1)
for i, a := range args[1:] {
if a != nil {
variadicArgs[i] = a.(interface{})
}
}
run(args[0].(string), variadicArgs...)
})
return _c
}
func (_c *MockInterface_Printf_Call) Return() *MockInterface_Printf_Call {
_c.Call.Return()
return _c
}
func (_c *MockInterface_Printf_Call) RunAndReturn(run func(string, ...interface{})) *MockInterface_Printf_Call {
_c.Run(run)
return _c
}
// V provides a mock function with given fields: level
func (_m *MockInterface) V(level int) logger.Verbose {
ret := _m.Called(level)
if len(ret) == 0 {
panic("no return value specified for V")
}
var r0 logger.Verbose
if rf, ok := ret.Get(0).(func(int) logger.Verbose); ok {
r0 = rf(level)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(logger.Verbose)
}
}
return r0
}
// MockInterface_V_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'V'
type MockInterface_V_Call struct {
*mock.Call
}
// V is a helper method to define mock.On call
// - level int
func (_e *MockInterface_Expecter) V(level interface{}) *MockInterface_V_Call {
return &MockInterface_V_Call{Call: _e.mock.On("V", level)}
}
func (_c *MockInterface_V_Call) Run(run func(level int)) *MockInterface_V_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(int))
})
return _c
}
func (_c *MockInterface_V_Call) Return(_a0 logger.Verbose) *MockInterface_V_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_V_Call) RunAndReturn(run func(int) logger.Verbose) *MockInterface_V_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,76 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package logger_mock
import mock "github.com/stretchr/testify/mock"
// MockVerbose is an autogenerated mock type for the Verbose type
type MockVerbose struct {
mock.Mock
}
type MockVerbose_Expecter struct {
mock *mock.Mock
}
func (_m *MockVerbose) EXPECT() *MockVerbose_Expecter {
return &MockVerbose_Expecter{mock: &_m.Mock}
}
// Infof provides a mock function with given fields: format, args
func (_m *MockVerbose) Infof(format string, args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, format)
_ca = append(_ca, args...)
_m.Called(_ca...)
}
// MockVerbose_Infof_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Infof'
type MockVerbose_Infof_Call struct {
*mock.Call
}
// Infof is a helper method to define mock.On call
// - format string
// - args ...interface{}
func (_e *MockVerbose_Expecter) Infof(format interface{}, args ...interface{}) *MockVerbose_Infof_Call {
return &MockVerbose_Infof_Call{Call: _e.mock.On("Infof",
append([]interface{}{format}, args...)...)}
}
func (_c *MockVerbose_Infof_Call) Run(run func(format string, args ...interface{})) *MockVerbose_Infof_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]interface{}, len(args)-1)
for i, a := range args[1:] {
if a != nil {
variadicArgs[i] = a.(interface{})
}
}
run(args[0].(string), variadicArgs...)
})
return _c
}
func (_c *MockVerbose_Infof_Call) Return() *MockVerbose_Infof_Call {
_c.Call.Return()
return _c
}
func (_c *MockVerbose_Infof_Call) RunAndReturn(run func(string, ...interface{})) *MockVerbose_Infof_Call {
_c.Run(run)
return _c
}
// NewMockVerbose creates a new instance of MockVerbose. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockVerbose(t interface {
mock.TestingT
Cleanup(func())
}) *MockVerbose {
mock := &MockVerbose{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,76 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package logger_mock
import mock "github.com/stretchr/testify/mock"
// MockgoLogger is an autogenerated mock type for the goLogger type
type MockgoLogger struct {
mock.Mock
}
type MockgoLogger_Expecter struct {
mock *mock.Mock
}
func (_m *MockgoLogger) EXPECT() *MockgoLogger_Expecter {
return &MockgoLogger_Expecter{mock: &_m.Mock}
}
// Printf provides a mock function with given fields: format, v
func (_m *MockgoLogger) Printf(format string, v ...interface{}) {
var _ca []interface{}
_ca = append(_ca, format)
_ca = append(_ca, v...)
_m.Called(_ca...)
}
// MockgoLogger_Printf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Printf'
type MockgoLogger_Printf_Call struct {
*mock.Call
}
// Printf is a helper method to define mock.On call
// - format string
// - v ...interface{}
func (_e *MockgoLogger_Expecter) Printf(format interface{}, v ...interface{}) *MockgoLogger_Printf_Call {
return &MockgoLogger_Printf_Call{Call: _e.mock.On("Printf",
append([]interface{}{format}, v...)...)}
}
func (_c *MockgoLogger_Printf_Call) Run(run func(format string, v ...interface{})) *MockgoLogger_Printf_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]interface{}, len(args)-1)
for i, a := range args[1:] {
if a != nil {
variadicArgs[i] = a.(interface{})
}
}
run(args[0].(string), variadicArgs...)
})
return _c
}
func (_c *MockgoLogger_Printf_Call) Return() *MockgoLogger_Printf_Call {
_c.Call.Return()
return _c
}
func (_c *MockgoLogger_Printf_Call) RunAndReturn(run func(string, ...interface{})) *MockgoLogger_Printf_Call {
_c.Run(run)
return _c
}
// NewMockgoLogger creates a new instance of MockgoLogger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockgoLogger(t interface {
mock.TestingT
Cleanup(func())
}) *MockgoLogger {
mock := &MockgoLogger{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,398 @@
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package logger_mock
import (
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/spf13/pflag"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// AddFlags provides a mock function for the type MockInterface
func (_mock *MockInterface) AddFlags(f *pflag.FlagSet) {
_mock.Called(f)
return
}
// MockInterface_AddFlags_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddFlags'
type MockInterface_AddFlags_Call struct {
*mock.Call
}
// AddFlags is a helper method to define mock.On call
// - f *pflag.FlagSet
func (_e *MockInterface_Expecter) AddFlags(f interface{}) *MockInterface_AddFlags_Call {
return &MockInterface_AddFlags_Call{Call: _e.mock.On("AddFlags", f)}
}
func (_c *MockInterface_AddFlags_Call) Run(run func(f *pflag.FlagSet)) *MockInterface_AddFlags_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 *pflag.FlagSet
if args[0] != nil {
arg0 = args[0].(*pflag.FlagSet)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_AddFlags_Call) Return() *MockInterface_AddFlags_Call {
_c.Call.Return()
return _c
}
func (_c *MockInterface_AddFlags_Call) RunAndReturn(run func(f *pflag.FlagSet)) *MockInterface_AddFlags_Call {
_c.Run(run)
return _c
}
// IsEnabled provides a mock function for the type MockInterface
func (_mock *MockInterface) IsEnabled(level int) bool {
ret := _mock.Called(level)
if len(ret) == 0 {
panic("no return value specified for IsEnabled")
}
var r0 bool
if returnFunc, ok := ret.Get(0).(func(int) bool); ok {
r0 = returnFunc(level)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// MockInterface_IsEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsEnabled'
type MockInterface_IsEnabled_Call struct {
*mock.Call
}
// IsEnabled is a helper method to define mock.On call
// - level int
func (_e *MockInterface_Expecter) IsEnabled(level interface{}) *MockInterface_IsEnabled_Call {
return &MockInterface_IsEnabled_Call{Call: _e.mock.On("IsEnabled", level)}
}
func (_c *MockInterface_IsEnabled_Call) Run(run func(level int)) *MockInterface_IsEnabled_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 int
if args[0] != nil {
arg0 = args[0].(int)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_IsEnabled_Call) Return(b bool) *MockInterface_IsEnabled_Call {
_c.Call.Return(b)
return _c
}
func (_c *MockInterface_IsEnabled_Call) RunAndReturn(run func(level int) bool) *MockInterface_IsEnabled_Call {
_c.Call.Return(run)
return _c
}
// Printf provides a mock function for the type MockInterface
func (_mock *MockInterface) Printf(format string, args ...interface{}) {
if len(args) > 0 {
_mock.Called(format, args)
} else {
_mock.Called(format)
}
return
}
// MockInterface_Printf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Printf'
type MockInterface_Printf_Call struct {
*mock.Call
}
// Printf is a helper method to define mock.On call
// - format string
// - args ...interface{}
func (_e *MockInterface_Expecter) Printf(format interface{}, args ...interface{}) *MockInterface_Printf_Call {
return &MockInterface_Printf_Call{Call: _e.mock.On("Printf",
append([]interface{}{format}, args...)...)}
}
func (_c *MockInterface_Printf_Call) Run(run func(format string, args ...interface{})) *MockInterface_Printf_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
var arg1 []interface{}
var variadicArgs []interface{}
if len(args) > 1 {
variadicArgs = args[1].([]interface{})
}
arg1 = variadicArgs
run(
arg0,
arg1...,
)
})
return _c
}
func (_c *MockInterface_Printf_Call) Return() *MockInterface_Printf_Call {
_c.Call.Return()
return _c
}
func (_c *MockInterface_Printf_Call) RunAndReturn(run func(format string, args ...interface{})) *MockInterface_Printf_Call {
_c.Run(run)
return _c
}
// V provides a mock function for the type MockInterface
func (_mock *MockInterface) V(level int) logger.Verbose {
ret := _mock.Called(level)
if len(ret) == 0 {
panic("no return value specified for V")
}
var r0 logger.Verbose
if returnFunc, ok := ret.Get(0).(func(int) logger.Verbose); ok {
r0 = returnFunc(level)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(logger.Verbose)
}
}
return r0
}
// MockInterface_V_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'V'
type MockInterface_V_Call struct {
*mock.Call
}
// V is a helper method to define mock.On call
// - level int
func (_e *MockInterface_Expecter) V(level interface{}) *MockInterface_V_Call {
return &MockInterface_V_Call{Call: _e.mock.On("V", level)}
}
func (_c *MockInterface_V_Call) Run(run func(level int)) *MockInterface_V_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 int
if args[0] != nil {
arg0 = args[0].(int)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_V_Call) Return(verbose logger.Verbose) *MockInterface_V_Call {
_c.Call.Return(verbose)
return _c
}
func (_c *MockInterface_V_Call) RunAndReturn(run func(level int) logger.Verbose) *MockInterface_V_Call {
_c.Call.Return(run)
return _c
}
// NewMockVerbose creates a new instance of MockVerbose. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockVerbose(t interface {
mock.TestingT
Cleanup(func())
}) *MockVerbose {
mock := &MockVerbose{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockVerbose is an autogenerated mock type for the Verbose type
type MockVerbose struct {
mock.Mock
}
type MockVerbose_Expecter struct {
mock *mock.Mock
}
func (_m *MockVerbose) EXPECT() *MockVerbose_Expecter {
return &MockVerbose_Expecter{mock: &_m.Mock}
}
// Infof provides a mock function for the type MockVerbose
func (_mock *MockVerbose) Infof(format string, args ...interface{}) {
if len(args) > 0 {
_mock.Called(format, args)
} else {
_mock.Called(format)
}
return
}
// MockVerbose_Infof_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Infof'
type MockVerbose_Infof_Call struct {
*mock.Call
}
// Infof is a helper method to define mock.On call
// - format string
// - args ...interface{}
func (_e *MockVerbose_Expecter) Infof(format interface{}, args ...interface{}) *MockVerbose_Infof_Call {
return &MockVerbose_Infof_Call{Call: _e.mock.On("Infof",
append([]interface{}{format}, args...)...)}
}
func (_c *MockVerbose_Infof_Call) Run(run func(format string, args ...interface{})) *MockVerbose_Infof_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
var arg1 []interface{}
var variadicArgs []interface{}
if len(args) > 1 {
variadicArgs = args[1].([]interface{})
}
arg1 = variadicArgs
run(
arg0,
arg1...,
)
})
return _c
}
func (_c *MockVerbose_Infof_Call) Return() *MockVerbose_Infof_Call {
_c.Call.Return()
return _c
}
func (_c *MockVerbose_Infof_Call) RunAndReturn(run func(format string, args ...interface{})) *MockVerbose_Infof_Call {
_c.Run(run)
return _c
}
// newMockgoLogger creates a new instance of mockgoLogger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func newMockgoLogger(t interface {
mock.TestingT
Cleanup(func())
}) *mockgoLogger {
mock := &mockgoLogger{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// mockgoLogger is an autogenerated mock type for the goLogger type
type mockgoLogger struct {
mock.Mock
}
type mockgoLogger_Expecter struct {
mock *mock.Mock
}
func (_m *mockgoLogger) EXPECT() *mockgoLogger_Expecter {
return &mockgoLogger_Expecter{mock: &_m.Mock}
}
// Printf provides a mock function for the type mockgoLogger
func (_mock *mockgoLogger) Printf(format string, v ...interface{}) {
if len(v) > 0 {
_mock.Called(format, v)
} else {
_mock.Called(format)
}
return
}
// mockgoLogger_Printf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Printf'
type mockgoLogger_Printf_Call struct {
*mock.Call
}
// Printf is a helper method to define mock.On call
// - format string
// - v ...interface{}
func (_e *mockgoLogger_Expecter) Printf(format interface{}, v ...interface{}) *mockgoLogger_Printf_Call {
return &mockgoLogger_Printf_Call{Call: _e.mock.On("Printf",
append([]interface{}{format}, v...)...)}
}
func (_c *mockgoLogger_Printf_Call) Run(run func(format string, v ...interface{})) *mockgoLogger_Printf_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
var arg1 []interface{}
var variadicArgs []interface{}
if len(args) > 1 {
variadicArgs = args[1].([]interface{})
}
arg1 = variadicArgs
run(
arg0,
arg1...,
)
})
return _c
}
func (_c *mockgoLogger_Printf_Call) Return() *mockgoLogger_Printf_Call {
_c.Call.Return()
return _c
}
func (_c *mockgoLogger_Printf_Call) RunAndReturn(run func(format string, v ...interface{})) *mockgoLogger_Printf_Call {
_c.Run(run)
return _c
}

View File

@@ -1,8 +1,26 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package reader_mock
import mock "github.com/stretchr/testify/mock"
import (
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
@@ -17,9 +35,9 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// ReadPassword provides a mock function with given fields: prompt
func (_m *MockInterface) ReadPassword(prompt string) (string, error) {
ret := _m.Called(prompt)
// ReadPassword provides a mock function for the type MockInterface
func (_mock *MockInterface) ReadPassword(prompt string) (string, error) {
ret := _mock.Called(prompt)
if len(ret) == 0 {
panic("no return value specified for ReadPassword")
@@ -27,21 +45,19 @@ func (_m *MockInterface) ReadPassword(prompt string) (string, error) {
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
return rf(prompt)
if returnFunc, ok := ret.Get(0).(func(string) (string, error)); ok {
return returnFunc(prompt)
}
if rf, ok := ret.Get(0).(func(string) string); ok {
r0 = rf(prompt)
if returnFunc, ok := ret.Get(0).(func(string) string); ok {
r0 = returnFunc(prompt)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(prompt)
if returnFunc, ok := ret.Get(1).(func(string) error); ok {
r1 = returnFunc(prompt)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
@@ -58,24 +74,30 @@ func (_e *MockInterface_Expecter) ReadPassword(prompt interface{}) *MockInterfac
func (_c *MockInterface_ReadPassword_Call) Run(run func(prompt string)) *MockInterface_ReadPassword_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_ReadPassword_Call) Return(_a0 string, _a1 error) *MockInterface_ReadPassword_Call {
_c.Call.Return(_a0, _a1)
func (_c *MockInterface_ReadPassword_Call) Return(s string, err error) *MockInterface_ReadPassword_Call {
_c.Call.Return(s, err)
return _c
}
func (_c *MockInterface_ReadPassword_Call) RunAndReturn(run func(string) (string, error)) *MockInterface_ReadPassword_Call {
func (_c *MockInterface_ReadPassword_Call) RunAndReturn(run func(prompt string) (string, error)) *MockInterface_ReadPassword_Call {
_c.Call.Return(run)
return _c
}
// ReadString provides a mock function with given fields: prompt
func (_m *MockInterface) ReadString(prompt string) (string, error) {
ret := _m.Called(prompt)
// ReadString provides a mock function for the type MockInterface
func (_mock *MockInterface) ReadString(prompt string) (string, error) {
ret := _mock.Called(prompt)
if len(ret) == 0 {
panic("no return value specified for ReadString")
@@ -83,21 +105,19 @@ func (_m *MockInterface) ReadString(prompt string) (string, error) {
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
return rf(prompt)
if returnFunc, ok := ret.Get(0).(func(string) (string, error)); ok {
return returnFunc(prompt)
}
if rf, ok := ret.Get(0).(func(string) string); ok {
r0 = rf(prompt)
if returnFunc, ok := ret.Get(0).(func(string) string); ok {
r0 = returnFunc(prompt)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(prompt)
if returnFunc, ok := ret.Get(1).(func(string) error); ok {
r1 = returnFunc(prompt)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
@@ -114,31 +134,23 @@ func (_e *MockInterface_Expecter) ReadString(prompt interface{}) *MockInterface_
func (_c *MockInterface_ReadString_Call) Run(run func(prompt string)) *MockInterface_ReadString_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_ReadString_Call) Return(_a0 string, _a1 error) *MockInterface_ReadString_Call {
_c.Call.Return(_a0, _a1)
func (_c *MockInterface_ReadString_Call) Return(s string, err error) *MockInterface_ReadString_Call {
_c.Call.Return(s, err)
return _c
}
func (_c *MockInterface_ReadString_Call) RunAndReturn(run func(string) (string, error)) *MockInterface_ReadString_Call {
func (_c *MockInterface_ReadString_Call) RunAndReturn(run func(prompt string) (string, error)) *MockInterface_ReadString_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,88 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package stdio_mock
import mock "github.com/stretchr/testify/mock"
// MockStdin is an autogenerated mock type for the Stdin type
type MockStdin struct {
mock.Mock
}
type MockStdin_Expecter struct {
mock *mock.Mock
}
func (_m *MockStdin) EXPECT() *MockStdin_Expecter {
return &MockStdin_Expecter{mock: &_m.Mock}
}
// Read provides a mock function with given fields: p
func (_m *MockStdin) Read(p []byte) (int, error) {
ret := _m.Called(p)
if len(ret) == 0 {
panic("no return value specified for Read")
}
var r0 int
var r1 error
if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok {
return rf(p)
}
if rf, ok := ret.Get(0).(func([]byte) int); ok {
r0 = rf(p)
} else {
r0 = ret.Get(0).(int)
}
if rf, ok := ret.Get(1).(func([]byte) error); ok {
r1 = rf(p)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockStdin_Read_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Read'
type MockStdin_Read_Call struct {
*mock.Call
}
// Read is a helper method to define mock.On call
// - p []byte
func (_e *MockStdin_Expecter) Read(p interface{}) *MockStdin_Read_Call {
return &MockStdin_Read_Call{Call: _e.mock.On("Read", p)}
}
func (_c *MockStdin_Read_Call) Run(run func(p []byte)) *MockStdin_Read_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].([]byte))
})
return _c
}
func (_c *MockStdin_Read_Call) Return(n int, err error) *MockStdin_Read_Call {
_c.Call.Return(n, err)
return _c
}
func (_c *MockStdin_Read_Call) RunAndReturn(run func([]byte) (int, error)) *MockStdin_Read_Call {
_c.Call.Return(run)
return _c
}
// NewMockStdin creates a new instance of MockStdin. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockStdin(t interface {
mock.TestingT
Cleanup(func())
}) *MockStdin {
mock := &MockStdin{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,88 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package stdio_mock
import mock "github.com/stretchr/testify/mock"
// MockStdout is an autogenerated mock type for the Stdout type
type MockStdout struct {
mock.Mock
}
type MockStdout_Expecter struct {
mock *mock.Mock
}
func (_m *MockStdout) EXPECT() *MockStdout_Expecter {
return &MockStdout_Expecter{mock: &_m.Mock}
}
// Write provides a mock function with given fields: p
func (_m *MockStdout) Write(p []byte) (int, error) {
ret := _m.Called(p)
if len(ret) == 0 {
panic("no return value specified for Write")
}
var r0 int
var r1 error
if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok {
return rf(p)
}
if rf, ok := ret.Get(0).(func([]byte) int); ok {
r0 = rf(p)
} else {
r0 = ret.Get(0).(int)
}
if rf, ok := ret.Get(1).(func([]byte) error); ok {
r1 = rf(p)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockStdout_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write'
type MockStdout_Write_Call struct {
*mock.Call
}
// Write is a helper method to define mock.On call
// - p []byte
func (_e *MockStdout_Expecter) Write(p interface{}) *MockStdout_Write_Call {
return &MockStdout_Write_Call{Call: _e.mock.On("Write", p)}
}
func (_c *MockStdout_Write_Call) Run(run func(p []byte)) *MockStdout_Write_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].([]byte))
})
return _c
}
func (_c *MockStdout_Write_Call) Return(n int, err error) *MockStdout_Write_Call {
_c.Call.Return(n, err)
return _c
}
func (_c *MockStdout_Write_Call) RunAndReturn(run func([]byte) (int, error)) *MockStdout_Write_Call {
_c.Call.Return(run)
return _c
}
// NewMockStdout creates a new instance of MockStdout. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockStdout(t interface {
mock.TestingT
Cleanup(func())
}) *MockStdout {
mock := &MockStdout{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,183 @@
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package stdio_mock
import (
mock "github.com/stretchr/testify/mock"
)
// NewMockStdout creates a new instance of MockStdout. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockStdout(t interface {
mock.TestingT
Cleanup(func())
}) *MockStdout {
mock := &MockStdout{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockStdout is an autogenerated mock type for the Stdout type
type MockStdout struct {
mock.Mock
}
type MockStdout_Expecter struct {
mock *mock.Mock
}
func (_m *MockStdout) EXPECT() *MockStdout_Expecter {
return &MockStdout_Expecter{mock: &_m.Mock}
}
// Write provides a mock function for the type MockStdout
func (_mock *MockStdout) Write(p []byte) (int, error) {
ret := _mock.Called(p)
if len(ret) == 0 {
panic("no return value specified for Write")
}
var r0 int
var r1 error
if returnFunc, ok := ret.Get(0).(func([]byte) (int, error)); ok {
return returnFunc(p)
}
if returnFunc, ok := ret.Get(0).(func([]byte) int); ok {
r0 = returnFunc(p)
} else {
r0 = ret.Get(0).(int)
}
if returnFunc, ok := ret.Get(1).(func([]byte) error); ok {
r1 = returnFunc(p)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockStdout_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write'
type MockStdout_Write_Call struct {
*mock.Call
}
// Write is a helper method to define mock.On call
// - p []byte
func (_e *MockStdout_Expecter) Write(p interface{}) *MockStdout_Write_Call {
return &MockStdout_Write_Call{Call: _e.mock.On("Write", p)}
}
func (_c *MockStdout_Write_Call) Run(run func(p []byte)) *MockStdout_Write_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 []byte
if args[0] != nil {
arg0 = args[0].([]byte)
}
run(
arg0,
)
})
return _c
}
func (_c *MockStdout_Write_Call) Return(n int, err error) *MockStdout_Write_Call {
_c.Call.Return(n, err)
return _c
}
func (_c *MockStdout_Write_Call) RunAndReturn(run func(p []byte) (int, error)) *MockStdout_Write_Call {
_c.Call.Return(run)
return _c
}
// NewMockStdin creates a new instance of MockStdin. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockStdin(t interface {
mock.TestingT
Cleanup(func())
}) *MockStdin {
mock := &MockStdin{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockStdin is an autogenerated mock type for the Stdin type
type MockStdin struct {
mock.Mock
}
type MockStdin_Expecter struct {
mock *mock.Mock
}
func (_m *MockStdin) EXPECT() *MockStdin_Expecter {
return &MockStdin_Expecter{mock: &_m.Mock}
}
// Read provides a mock function for the type MockStdin
func (_mock *MockStdin) Read(p []byte) (int, error) {
ret := _mock.Called(p)
if len(ret) == 0 {
panic("no return value specified for Read")
}
var r0 int
var r1 error
if returnFunc, ok := ret.Get(0).(func([]byte) (int, error)); ok {
return returnFunc(p)
}
if returnFunc, ok := ret.Get(0).(func([]byte) int); ok {
r0 = returnFunc(p)
} else {
r0 = ret.Get(0).(int)
}
if returnFunc, ok := ret.Get(1).(func([]byte) error); ok {
r1 = returnFunc(p)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockStdin_Read_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Read'
type MockStdin_Read_Call struct {
*mock.Call
}
// Read is a helper method to define mock.On call
// - p []byte
func (_e *MockStdin_Expecter) Read(p interface{}) *MockStdin_Read_Call {
return &MockStdin_Read_Call{Call: _e.mock.On("Read", p)}
}
func (_c *MockStdin_Read_Call) Run(run func(p []byte)) *MockStdin_Read_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 []byte
if args[0] != nil {
arg0 = args[0].([]byte)
}
run(
arg0,
)
})
return _c
}
func (_c *MockStdin_Read_Call) Return(n int, err error) *MockStdin_Read_Call {
_c.Call.Return(n, err)
return _c
}
func (_c *MockStdin_Read_Call) RunAndReturn(run func(p []byte) (int, error)) *MockStdin_Read_Call {
_c.Call.Return(run)
return _c
}

View File

@@ -1,13 +1,29 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package jwt_mock
import (
time "time"
"time"
mock "github.com/stretchr/testify/mock"
)
// NewMockClock creates a new instance of MockClock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockClock(t interface {
mock.TestingT
Cleanup(func())
}) *MockClock {
mock := &MockClock{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockClock is an autogenerated mock type for the Clock type
type MockClock struct {
mock.Mock
@@ -21,21 +37,20 @@ func (_m *MockClock) EXPECT() *MockClock_Expecter {
return &MockClock_Expecter{mock: &_m.Mock}
}
// Now provides a mock function with no fields
func (_m *MockClock) Now() time.Time {
ret := _m.Called()
// Now provides a mock function for the type MockClock
func (_mock *MockClock) Now() time.Time {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for Now")
}
var r0 time.Time
if rf, ok := ret.Get(0).(func() time.Time); ok {
r0 = rf()
if returnFunc, ok := ret.Get(0).(func() time.Time); ok {
r0 = returnFunc()
} else {
r0 = ret.Get(0).(time.Time)
}
return r0
}
@@ -56,8 +71,8 @@ func (_c *MockClock_Now_Call) Run(run func()) *MockClock_Now_Call {
return _c
}
func (_c *MockClock_Now_Call) Return(_a0 time.Time) *MockClock_Now_Call {
_c.Call.Return(_a0)
func (_c *MockClock_Now_Call) Return(time1 time.Time) *MockClock_Now_Call {
_c.Call.Return(time1)
return _c
}
@@ -65,17 +80,3 @@ func (_c *MockClock_Now_Call) RunAndReturn(run func() time.Time) *MockClock_Now_
_c.Call.Return(run)
return _c
}
// NewMockClock creates a new instance of MockClock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockClock(t interface {
mock.TestingT
Cleanup(func())
}) *MockClock {
mock := &MockClock{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,13 +1,28 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package loader_mock
import (
kubeconfig "github.com/int128/kubelogin/pkg/kubeconfig"
"github.com/int128/kubelogin/pkg/kubeconfig"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -21,9 +36,9 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// GetCurrentAuthProvider provides a mock function with given fields: explicitFilename, contextName, userName
func (_m *MockInterface) GetCurrentAuthProvider(explicitFilename string, contextName kubeconfig.ContextName, userName kubeconfig.UserName) (*kubeconfig.AuthProvider, error) {
ret := _m.Called(explicitFilename, contextName, userName)
// GetCurrentAuthProvider provides a mock function for the type MockInterface
func (_mock *MockInterface) GetCurrentAuthProvider(explicitFilename string, contextName kubeconfig.ContextName, userName kubeconfig.UserName) (*kubeconfig.AuthProvider, error) {
ret := _mock.Called(explicitFilename, contextName, userName)
if len(ret) == 0 {
panic("no return value specified for GetCurrentAuthProvider")
@@ -31,23 +46,21 @@ func (_m *MockInterface) GetCurrentAuthProvider(explicitFilename string, context
var r0 *kubeconfig.AuthProvider
var r1 error
if rf, ok := ret.Get(0).(func(string, kubeconfig.ContextName, kubeconfig.UserName) (*kubeconfig.AuthProvider, error)); ok {
return rf(explicitFilename, contextName, userName)
if returnFunc, ok := ret.Get(0).(func(string, kubeconfig.ContextName, kubeconfig.UserName) (*kubeconfig.AuthProvider, error)); ok {
return returnFunc(explicitFilename, contextName, userName)
}
if rf, ok := ret.Get(0).(func(string, kubeconfig.ContextName, kubeconfig.UserName) *kubeconfig.AuthProvider); ok {
r0 = rf(explicitFilename, contextName, userName)
if returnFunc, ok := ret.Get(0).(func(string, kubeconfig.ContextName, kubeconfig.UserName) *kubeconfig.AuthProvider); ok {
r0 = returnFunc(explicitFilename, contextName, userName)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*kubeconfig.AuthProvider)
}
}
if rf, ok := ret.Get(1).(func(string, kubeconfig.ContextName, kubeconfig.UserName) error); ok {
r1 = rf(explicitFilename, contextName, userName)
if returnFunc, ok := ret.Get(1).(func(string, kubeconfig.ContextName, kubeconfig.UserName) error); ok {
r1 = returnFunc(explicitFilename, contextName, userName)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
@@ -66,31 +79,33 @@ func (_e *MockInterface_Expecter) GetCurrentAuthProvider(explicitFilename interf
func (_c *MockInterface_GetCurrentAuthProvider_Call) Run(run func(explicitFilename string, contextName kubeconfig.ContextName, userName kubeconfig.UserName)) *MockInterface_GetCurrentAuthProvider_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(kubeconfig.ContextName), args[2].(kubeconfig.UserName))
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
var arg1 kubeconfig.ContextName
if args[1] != nil {
arg1 = args[1].(kubeconfig.ContextName)
}
var arg2 kubeconfig.UserName
if args[2] != nil {
arg2 = args[2].(kubeconfig.UserName)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockInterface_GetCurrentAuthProvider_Call) Return(_a0 *kubeconfig.AuthProvider, _a1 error) *MockInterface_GetCurrentAuthProvider_Call {
_c.Call.Return(_a0, _a1)
func (_c *MockInterface_GetCurrentAuthProvider_Call) Return(authProvider *kubeconfig.AuthProvider, err error) *MockInterface_GetCurrentAuthProvider_Call {
_c.Call.Return(authProvider, err)
return _c
}
func (_c *MockInterface_GetCurrentAuthProvider_Call) RunAndReturn(run func(string, kubeconfig.ContextName, kubeconfig.UserName) (*kubeconfig.AuthProvider, error)) *MockInterface_GetCurrentAuthProvider_Call {
func (_c *MockInterface_GetCurrentAuthProvider_Call) RunAndReturn(run func(explicitFilename string, contextName kubeconfig.ContextName, userName kubeconfig.UserName) (*kubeconfig.AuthProvider, error)) *MockInterface_GetCurrentAuthProvider_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,12 +1,28 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package writer_mock
import (
kubeconfig "github.com/int128/kubelogin/pkg/kubeconfig"
"github.com/int128/kubelogin/pkg/kubeconfig"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -20,21 +36,20 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// UpdateAuthProvider provides a mock function with given fields: p
func (_m *MockInterface) UpdateAuthProvider(p kubeconfig.AuthProvider) error {
ret := _m.Called(p)
// UpdateAuthProvider provides a mock function for the type MockInterface
func (_mock *MockInterface) UpdateAuthProvider(p kubeconfig.AuthProvider) error {
ret := _mock.Called(p)
if len(ret) == 0 {
panic("no return value specified for UpdateAuthProvider")
}
var r0 error
if rf, ok := ret.Get(0).(func(kubeconfig.AuthProvider) error); ok {
r0 = rf(p)
if returnFunc, ok := ret.Get(0).(func(kubeconfig.AuthProvider) error); ok {
r0 = returnFunc(p)
} else {
r0 = ret.Error(0)
}
return r0
}
@@ -51,31 +66,23 @@ func (_e *MockInterface_Expecter) UpdateAuthProvider(p interface{}) *MockInterfa
func (_c *MockInterface_UpdateAuthProvider_Call) Run(run func(p kubeconfig.AuthProvider)) *MockInterface_UpdateAuthProvider_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(kubeconfig.AuthProvider))
var arg0 kubeconfig.AuthProvider
if args[0] != nil {
arg0 = args[0].(kubeconfig.AuthProvider)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_UpdateAuthProvider_Call) Return(_a0 error) *MockInterface_UpdateAuthProvider_Call {
_c.Call.Return(_a0)
func (_c *MockInterface_UpdateAuthProvider_Call) Return(err error) *MockInterface_UpdateAuthProvider_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_UpdateAuthProvider_Call) RunAndReturn(run func(kubeconfig.AuthProvider) error) *MockInterface_UpdateAuthProvider_Call {
func (_c *MockInterface_UpdateAuthProvider_Call) RunAndReturn(run func(p kubeconfig.AuthProvider) error) *MockInterface_UpdateAuthProvider_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,102 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package client_mock
import (
context "context"
client "github.com/int128/kubelogin/pkg/oidc/client"
mock "github.com/stretchr/testify/mock"
oidc "github.com/int128/kubelogin/pkg/oidc"
tlsclientconfig "github.com/int128/kubelogin/pkg/tlsclientconfig"
)
// MockFactoryInterface is an autogenerated mock type for the FactoryInterface type
type MockFactoryInterface struct {
mock.Mock
}
type MockFactoryInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockFactoryInterface) EXPECT() *MockFactoryInterface_Expecter {
return &MockFactoryInterface_Expecter{mock: &_m.Mock}
}
// New provides a mock function with given fields: ctx, p, tlsClientConfig
func (_m *MockFactoryInterface) New(ctx context.Context, p oidc.Provider, tlsClientConfig tlsclientconfig.Config) (client.Interface, error) {
ret := _m.Called(ctx, p, tlsClientConfig)
if len(ret) == 0 {
panic("no return value specified for New")
}
var r0 client.Interface
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, oidc.Provider, tlsclientconfig.Config) (client.Interface, error)); ok {
return rf(ctx, p, tlsClientConfig)
}
if rf, ok := ret.Get(0).(func(context.Context, oidc.Provider, tlsclientconfig.Config) client.Interface); ok {
r0 = rf(ctx, p, tlsClientConfig)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(client.Interface)
}
}
if rf, ok := ret.Get(1).(func(context.Context, oidc.Provider, tlsclientconfig.Config) error); ok {
r1 = rf(ctx, p, tlsClientConfig)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockFactoryInterface_New_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'New'
type MockFactoryInterface_New_Call struct {
*mock.Call
}
// New is a helper method to define mock.On call
// - ctx context.Context
// - p oidc.Provider
// - tlsClientConfig tlsclientconfig.Config
func (_e *MockFactoryInterface_Expecter) New(ctx interface{}, p interface{}, tlsClientConfig interface{}) *MockFactoryInterface_New_Call {
return &MockFactoryInterface_New_Call{Call: _e.mock.On("New", ctx, p, tlsClientConfig)}
}
func (_c *MockFactoryInterface_New_Call) Run(run func(ctx context.Context, p oidc.Provider, tlsClientConfig tlsclientconfig.Config)) *MockFactoryInterface_New_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(oidc.Provider), args[2].(tlsclientconfig.Config))
})
return _c
}
func (_c *MockFactoryInterface_New_Call) Return(_a0 client.Interface, _a1 error) *MockFactoryInterface_New_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockFactoryInterface_New_Call) RunAndReturn(run func(context.Context, oidc.Provider, tlsclientconfig.Config) (client.Interface, error)) *MockFactoryInterface_New_Call {
_c.Call.Return(run)
return _c
}
// NewMockFactoryInterface creates a new instance of MockFactoryInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockFactoryInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockFactoryInterface {
mock := &MockFactoryInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,490 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package client_mock
import (
context "context"
client "github.com/int128/kubelogin/pkg/oidc/client"
mock "github.com/stretchr/testify/mock"
oauth2dev "github.com/int128/oauth2dev"
oidc "github.com/int128/kubelogin/pkg/oidc"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// ExchangeAuthCode provides a mock function with given fields: ctx, in
func (_m *MockInterface) ExchangeAuthCode(ctx context.Context, in client.ExchangeAuthCodeInput) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for ExchangeAuthCode")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, client.ExchangeAuthCodeInput) (*oidc.TokenSet, error)); ok {
return rf(ctx, in)
}
if rf, ok := ret.Get(0).(func(context.Context, client.ExchangeAuthCodeInput) *oidc.TokenSet); ok {
r0 = rf(ctx, in)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, client.ExchangeAuthCodeInput) error); ok {
r1 = rf(ctx, in)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_ExchangeAuthCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExchangeAuthCode'
type MockInterface_ExchangeAuthCode_Call struct {
*mock.Call
}
// ExchangeAuthCode is a helper method to define mock.On call
// - ctx context.Context
// - in client.ExchangeAuthCodeInput
func (_e *MockInterface_Expecter) ExchangeAuthCode(ctx interface{}, in interface{}) *MockInterface_ExchangeAuthCode_Call {
return &MockInterface_ExchangeAuthCode_Call{Call: _e.mock.On("ExchangeAuthCode", ctx, in)}
}
func (_c *MockInterface_ExchangeAuthCode_Call) Run(run func(ctx context.Context, in client.ExchangeAuthCodeInput)) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(client.ExchangeAuthCodeInput))
})
return _c
}
func (_c *MockInterface_ExchangeAuthCode_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_ExchangeAuthCode_Call) RunAndReturn(run func(context.Context, client.ExchangeAuthCodeInput) (*oidc.TokenSet, error)) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Return(run)
return _c
}
// ExchangeDeviceCode provides a mock function with given fields: ctx, authResponse
func (_m *MockInterface) ExchangeDeviceCode(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, authResponse)
if len(ret) == 0 {
panic("no return value specified for ExchangeDeviceCode")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error)); ok {
return rf(ctx, authResponse)
}
if rf, ok := ret.Get(0).(func(context.Context, *oauth2dev.AuthorizationResponse) *oidc.TokenSet); ok {
r0 = rf(ctx, authResponse)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *oauth2dev.AuthorizationResponse) error); ok {
r1 = rf(ctx, authResponse)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_ExchangeDeviceCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExchangeDeviceCode'
type MockInterface_ExchangeDeviceCode_Call struct {
*mock.Call
}
// ExchangeDeviceCode is a helper method to define mock.On call
// - ctx context.Context
// - authResponse *oauth2dev.AuthorizationResponse
func (_e *MockInterface_Expecter) ExchangeDeviceCode(ctx interface{}, authResponse interface{}) *MockInterface_ExchangeDeviceCode_Call {
return &MockInterface_ExchangeDeviceCode_Call{Call: _e.mock.On("ExchangeDeviceCode", ctx, authResponse)}
}
func (_c *MockInterface_ExchangeDeviceCode_Call) Run(run func(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse)) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*oauth2dev.AuthorizationResponse))
})
return _c
}
func (_c *MockInterface_ExchangeDeviceCode_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_ExchangeDeviceCode_Call) RunAndReturn(run func(context.Context, *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error)) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Return(run)
return _c
}
// GetAuthCodeURL provides a mock function with given fields: in
func (_m *MockInterface) GetAuthCodeURL(in client.AuthCodeURLInput) string {
ret := _m.Called(in)
if len(ret) == 0 {
panic("no return value specified for GetAuthCodeURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(client.AuthCodeURLInput) string); ok {
r0 = rf(in)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// MockInterface_GetAuthCodeURL_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAuthCodeURL'
type MockInterface_GetAuthCodeURL_Call struct {
*mock.Call
}
// GetAuthCodeURL is a helper method to define mock.On call
// - in client.AuthCodeURLInput
func (_e *MockInterface_Expecter) GetAuthCodeURL(in interface{}) *MockInterface_GetAuthCodeURL_Call {
return &MockInterface_GetAuthCodeURL_Call{Call: _e.mock.On("GetAuthCodeURL", in)}
}
func (_c *MockInterface_GetAuthCodeURL_Call) Run(run func(in client.AuthCodeURLInput)) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(client.AuthCodeURLInput))
})
return _c
}
func (_c *MockInterface_GetAuthCodeURL_Call) Return(_a0 string) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_GetAuthCodeURL_Call) RunAndReturn(run func(client.AuthCodeURLInput) string) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Return(run)
return _c
}
// GetDeviceAuthorization provides a mock function with given fields: ctx
func (_m *MockInterface) GetDeviceAuthorization(ctx context.Context) (*oauth2dev.AuthorizationResponse, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetDeviceAuthorization")
}
var r0 *oauth2dev.AuthorizationResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (*oauth2dev.AuthorizationResponse, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) *oauth2dev.AuthorizationResponse); ok {
r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oauth2dev.AuthorizationResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetDeviceAuthorization_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDeviceAuthorization'
type MockInterface_GetDeviceAuthorization_Call struct {
*mock.Call
}
// GetDeviceAuthorization is a helper method to define mock.On call
// - ctx context.Context
func (_e *MockInterface_Expecter) GetDeviceAuthorization(ctx interface{}) *MockInterface_GetDeviceAuthorization_Call {
return &MockInterface_GetDeviceAuthorization_Call{Call: _e.mock.On("GetDeviceAuthorization", ctx)}
}
func (_c *MockInterface_GetDeviceAuthorization_Call) Run(run func(ctx context.Context)) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context))
})
return _c
}
func (_c *MockInterface_GetDeviceAuthorization_Call) Return(_a0 *oauth2dev.AuthorizationResponse, _a1 error) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_GetDeviceAuthorization_Call) RunAndReturn(run func(context.Context) (*oauth2dev.AuthorizationResponse, error)) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Return(run)
return _c
}
// GetTokenByAuthCode provides a mock function with given fields: ctx, in, localServerReadyChan
func (_m *MockInterface) GetTokenByAuthCode(ctx context.Context, in client.GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, in, localServerReadyChan)
if len(ret) == 0 {
panic("no return value specified for GetTokenByAuthCode")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) (*oidc.TokenSet, error)); ok {
return rf(ctx, in, localServerReadyChan)
}
if rf, ok := ret.Get(0).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) *oidc.TokenSet); ok {
r0 = rf(ctx, in, localServerReadyChan)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) error); ok {
r1 = rf(ctx, in, localServerReadyChan)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetTokenByAuthCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenByAuthCode'
type MockInterface_GetTokenByAuthCode_Call struct {
*mock.Call
}
// GetTokenByAuthCode is a helper method to define mock.On call
// - ctx context.Context
// - in client.GetTokenByAuthCodeInput
// - localServerReadyChan chan<- string
func (_e *MockInterface_Expecter) GetTokenByAuthCode(ctx interface{}, in interface{}, localServerReadyChan interface{}) *MockInterface_GetTokenByAuthCode_Call {
return &MockInterface_GetTokenByAuthCode_Call{Call: _e.mock.On("GetTokenByAuthCode", ctx, in, localServerReadyChan)}
}
func (_c *MockInterface_GetTokenByAuthCode_Call) Run(run func(ctx context.Context, in client.GetTokenByAuthCodeInput, localServerReadyChan chan<- string)) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(client.GetTokenByAuthCodeInput), args[2].(chan<- string))
})
return _c
}
func (_c *MockInterface_GetTokenByAuthCode_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_GetTokenByAuthCode_Call) RunAndReturn(run func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) (*oidc.TokenSet, error)) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Return(run)
return _c
}
// GetTokenByROPC provides a mock function with given fields: ctx, username, password
func (_m *MockInterface) GetTokenByROPC(ctx context.Context, username string, password string) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, username, password)
if len(ret) == 0 {
panic("no return value specified for GetTokenByROPC")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (*oidc.TokenSet, error)); ok {
return rf(ctx, username, password)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) *oidc.TokenSet); ok {
r0 = rf(ctx, username, password)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, username, password)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetTokenByROPC_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenByROPC'
type MockInterface_GetTokenByROPC_Call struct {
*mock.Call
}
// GetTokenByROPC is a helper method to define mock.On call
// - ctx context.Context
// - username string
// - password string
func (_e *MockInterface_Expecter) GetTokenByROPC(ctx interface{}, username interface{}, password interface{}) *MockInterface_GetTokenByROPC_Call {
return &MockInterface_GetTokenByROPC_Call{Call: _e.mock.On("GetTokenByROPC", ctx, username, password)}
}
func (_c *MockInterface_GetTokenByROPC_Call) Run(run func(ctx context.Context, username string, password string)) *MockInterface_GetTokenByROPC_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockInterface_GetTokenByROPC_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_GetTokenByROPC_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_GetTokenByROPC_Call) RunAndReturn(run func(context.Context, string, string) (*oidc.TokenSet, error)) *MockInterface_GetTokenByROPC_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function with given fields: ctx, refreshToken
func (_m *MockInterface) Refresh(ctx context.Context, refreshToken string) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (*oidc.TokenSet, error)); ok {
return rf(ctx, refreshToken)
}
if rf, ok := ret.Get(0).(func(context.Context, string) *oidc.TokenSet); ok {
r0 = rf(ctx, refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockInterface_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - ctx context.Context
// - refreshToken string
func (_e *MockInterface_Expecter) Refresh(ctx interface{}, refreshToken interface{}) *MockInterface_Refresh_Call {
return &MockInterface_Refresh_Call{Call: _e.mock.On("Refresh", ctx, refreshToken)}
}
func (_c *MockInterface_Refresh_Call) Run(run func(ctx context.Context, refreshToken string)) *MockInterface_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string))
})
return _c
}
func (_c *MockInterface_Refresh_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_Refresh_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_Refresh_Call) RunAndReturn(run func(context.Context, string) (*oidc.TokenSet, error)) *MockInterface_Refresh_Call {
_c.Call.Return(run)
return _c
}
// SupportedPKCEMethods provides a mock function with no fields
func (_m *MockInterface) SupportedPKCEMethods() []string {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for SupportedPKCEMethods")
}
var r0 []string
if rf, ok := ret.Get(0).(func() []string); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
return r0
}
// MockInterface_SupportedPKCEMethods_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SupportedPKCEMethods'
type MockInterface_SupportedPKCEMethods_Call struct {
*mock.Call
}
// SupportedPKCEMethods is a helper method to define mock.On call
func (_e *MockInterface_Expecter) SupportedPKCEMethods() *MockInterface_SupportedPKCEMethods_Call {
return &MockInterface_SupportedPKCEMethods_Call{Call: _e.mock.On("SupportedPKCEMethods")}
}
func (_c *MockInterface_SupportedPKCEMethods_Call) Run(run func()) *MockInterface_SupportedPKCEMethods_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockInterface_SupportedPKCEMethods_Call) Return(_a0 []string) *MockInterface_SupportedPKCEMethods_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_SupportedPKCEMethods_Call) RunAndReturn(run func() []string) *MockInterface_SupportedPKCEMethods_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,721 @@
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package client_mock
import (
"context"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client"
"github.com/int128/kubelogin/pkg/pkce"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
"github.com/int128/oauth2dev"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// ExchangeAuthCode provides a mock function for the type MockInterface
func (_mock *MockInterface) ExchangeAuthCode(ctx context.Context, in client.ExchangeAuthCodeInput) (*oidc.TokenSet, error) {
ret := _mock.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for ExchangeAuthCode")
}
var r0 *oidc.TokenSet
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, client.ExchangeAuthCodeInput) (*oidc.TokenSet, error)); ok {
return returnFunc(ctx, in)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, client.ExchangeAuthCodeInput) *oidc.TokenSet); ok {
r0 = returnFunc(ctx, in)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, client.ExchangeAuthCodeInput) error); ok {
r1 = returnFunc(ctx, in)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_ExchangeAuthCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExchangeAuthCode'
type MockInterface_ExchangeAuthCode_Call struct {
*mock.Call
}
// ExchangeAuthCode is a helper method to define mock.On call
// - ctx context.Context
// - in client.ExchangeAuthCodeInput
func (_e *MockInterface_Expecter) ExchangeAuthCode(ctx interface{}, in interface{}) *MockInterface_ExchangeAuthCode_Call {
return &MockInterface_ExchangeAuthCode_Call{Call: _e.mock.On("ExchangeAuthCode", ctx, in)}
}
func (_c *MockInterface_ExchangeAuthCode_Call) Run(run func(ctx context.Context, in client.ExchangeAuthCodeInput)) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 client.ExchangeAuthCodeInput
if args[1] != nil {
arg1 = args[1].(client.ExchangeAuthCodeInput)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_ExchangeAuthCode_Call) Return(tokenSet *oidc.TokenSet, err error) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Return(tokenSet, err)
return _c
}
func (_c *MockInterface_ExchangeAuthCode_Call) RunAndReturn(run func(ctx context.Context, in client.ExchangeAuthCodeInput) (*oidc.TokenSet, error)) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Return(run)
return _c
}
// ExchangeDeviceCode provides a mock function for the type MockInterface
func (_mock *MockInterface) ExchangeDeviceCode(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error) {
ret := _mock.Called(ctx, authResponse)
if len(ret) == 0 {
panic("no return value specified for ExchangeDeviceCode")
}
var r0 *oidc.TokenSet
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error)); ok {
return returnFunc(ctx, authResponse)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, *oauth2dev.AuthorizationResponse) *oidc.TokenSet); ok {
r0 = returnFunc(ctx, authResponse)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, *oauth2dev.AuthorizationResponse) error); ok {
r1 = returnFunc(ctx, authResponse)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_ExchangeDeviceCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExchangeDeviceCode'
type MockInterface_ExchangeDeviceCode_Call struct {
*mock.Call
}
// ExchangeDeviceCode is a helper method to define mock.On call
// - ctx context.Context
// - authResponse *oauth2dev.AuthorizationResponse
func (_e *MockInterface_Expecter) ExchangeDeviceCode(ctx interface{}, authResponse interface{}) *MockInterface_ExchangeDeviceCode_Call {
return &MockInterface_ExchangeDeviceCode_Call{Call: _e.mock.On("ExchangeDeviceCode", ctx, authResponse)}
}
func (_c *MockInterface_ExchangeDeviceCode_Call) Run(run func(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse)) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 *oauth2dev.AuthorizationResponse
if args[1] != nil {
arg1 = args[1].(*oauth2dev.AuthorizationResponse)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_ExchangeDeviceCode_Call) Return(tokenSet *oidc.TokenSet, err error) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Return(tokenSet, err)
return _c
}
func (_c *MockInterface_ExchangeDeviceCode_Call) RunAndReturn(run func(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error)) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Return(run)
return _c
}
// GetAuthCodeURL provides a mock function for the type MockInterface
func (_mock *MockInterface) GetAuthCodeURL(in client.AuthCodeURLInput) string {
ret := _mock.Called(in)
if len(ret) == 0 {
panic("no return value specified for GetAuthCodeURL")
}
var r0 string
if returnFunc, ok := ret.Get(0).(func(client.AuthCodeURLInput) string); ok {
r0 = returnFunc(in)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// MockInterface_GetAuthCodeURL_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAuthCodeURL'
type MockInterface_GetAuthCodeURL_Call struct {
*mock.Call
}
// GetAuthCodeURL is a helper method to define mock.On call
// - in client.AuthCodeURLInput
func (_e *MockInterface_Expecter) GetAuthCodeURL(in interface{}) *MockInterface_GetAuthCodeURL_Call {
return &MockInterface_GetAuthCodeURL_Call{Call: _e.mock.On("GetAuthCodeURL", in)}
}
func (_c *MockInterface_GetAuthCodeURL_Call) Run(run func(in client.AuthCodeURLInput)) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 client.AuthCodeURLInput
if args[0] != nil {
arg0 = args[0].(client.AuthCodeURLInput)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_GetAuthCodeURL_Call) Return(s string) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Return(s)
return _c
}
func (_c *MockInterface_GetAuthCodeURL_Call) RunAndReturn(run func(in client.AuthCodeURLInput) string) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Return(run)
return _c
}
// GetDeviceAuthorization provides a mock function for the type MockInterface
func (_mock *MockInterface) GetDeviceAuthorization(ctx context.Context) (*oauth2dev.AuthorizationResponse, error) {
ret := _mock.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetDeviceAuthorization")
}
var r0 *oauth2dev.AuthorizationResponse
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context) (*oauth2dev.AuthorizationResponse, error)); ok {
return returnFunc(ctx)
}
if returnFunc, ok := ret.Get(0).(func(context.Context) *oauth2dev.AuthorizationResponse); ok {
r0 = returnFunc(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oauth2dev.AuthorizationResponse)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = returnFunc(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetDeviceAuthorization_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDeviceAuthorization'
type MockInterface_GetDeviceAuthorization_Call struct {
*mock.Call
}
// GetDeviceAuthorization is a helper method to define mock.On call
// - ctx context.Context
func (_e *MockInterface_Expecter) GetDeviceAuthorization(ctx interface{}) *MockInterface_GetDeviceAuthorization_Call {
return &MockInterface_GetDeviceAuthorization_Call{Call: _e.mock.On("GetDeviceAuthorization", ctx)}
}
func (_c *MockInterface_GetDeviceAuthorization_Call) Run(run func(ctx context.Context)) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_GetDeviceAuthorization_Call) Return(authorizationResponse *oauth2dev.AuthorizationResponse, err error) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Return(authorizationResponse, err)
return _c
}
func (_c *MockInterface_GetDeviceAuthorization_Call) RunAndReturn(run func(ctx context.Context) (*oauth2dev.AuthorizationResponse, error)) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Return(run)
return _c
}
// GetTokenByAuthCode provides a mock function for the type MockInterface
func (_mock *MockInterface) GetTokenByAuthCode(ctx context.Context, in client.GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error) {
ret := _mock.Called(ctx, in, localServerReadyChan)
if len(ret) == 0 {
panic("no return value specified for GetTokenByAuthCode")
}
var r0 *oidc.TokenSet
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) (*oidc.TokenSet, error)); ok {
return returnFunc(ctx, in, localServerReadyChan)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) *oidc.TokenSet); ok {
r0 = returnFunc(ctx, in, localServerReadyChan)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) error); ok {
r1 = returnFunc(ctx, in, localServerReadyChan)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetTokenByAuthCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenByAuthCode'
type MockInterface_GetTokenByAuthCode_Call struct {
*mock.Call
}
// GetTokenByAuthCode is a helper method to define mock.On call
// - ctx context.Context
// - in client.GetTokenByAuthCodeInput
// - localServerReadyChan chan<- string
func (_e *MockInterface_Expecter) GetTokenByAuthCode(ctx interface{}, in interface{}, localServerReadyChan interface{}) *MockInterface_GetTokenByAuthCode_Call {
return &MockInterface_GetTokenByAuthCode_Call{Call: _e.mock.On("GetTokenByAuthCode", ctx, in, localServerReadyChan)}
}
func (_c *MockInterface_GetTokenByAuthCode_Call) Run(run func(ctx context.Context, in client.GetTokenByAuthCodeInput, localServerReadyChan chan<- string)) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 client.GetTokenByAuthCodeInput
if args[1] != nil {
arg1 = args[1].(client.GetTokenByAuthCodeInput)
}
var arg2 chan<- string
if args[2] != nil {
arg2 = args[2].(chan<- string)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockInterface_GetTokenByAuthCode_Call) Return(tokenSet *oidc.TokenSet, err error) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Return(tokenSet, err)
return _c
}
func (_c *MockInterface_GetTokenByAuthCode_Call) RunAndReturn(run func(ctx context.Context, in client.GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error)) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Return(run)
return _c
}
// GetTokenByClientCredentials provides a mock function for the type MockInterface
func (_mock *MockInterface) GetTokenByClientCredentials(ctx context.Context, in client.GetTokenByClientCredentialsInput) (*oidc.TokenSet, error) {
ret := _mock.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for GetTokenByClientCredentials")
}
var r0 *oidc.TokenSet
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, client.GetTokenByClientCredentialsInput) (*oidc.TokenSet, error)); ok {
return returnFunc(ctx, in)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, client.GetTokenByClientCredentialsInput) *oidc.TokenSet); ok {
r0 = returnFunc(ctx, in)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, client.GetTokenByClientCredentialsInput) error); ok {
r1 = returnFunc(ctx, in)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetTokenByClientCredentials_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenByClientCredentials'
type MockInterface_GetTokenByClientCredentials_Call struct {
*mock.Call
}
// GetTokenByClientCredentials is a helper method to define mock.On call
// - ctx context.Context
// - in client.GetTokenByClientCredentialsInput
func (_e *MockInterface_Expecter) GetTokenByClientCredentials(ctx interface{}, in interface{}) *MockInterface_GetTokenByClientCredentials_Call {
return &MockInterface_GetTokenByClientCredentials_Call{Call: _e.mock.On("GetTokenByClientCredentials", ctx, in)}
}
func (_c *MockInterface_GetTokenByClientCredentials_Call) Run(run func(ctx context.Context, in client.GetTokenByClientCredentialsInput)) *MockInterface_GetTokenByClientCredentials_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 client.GetTokenByClientCredentialsInput
if args[1] != nil {
arg1 = args[1].(client.GetTokenByClientCredentialsInput)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_GetTokenByClientCredentials_Call) Return(tokenSet *oidc.TokenSet, err error) *MockInterface_GetTokenByClientCredentials_Call {
_c.Call.Return(tokenSet, err)
return _c
}
func (_c *MockInterface_GetTokenByClientCredentials_Call) RunAndReturn(run func(ctx context.Context, in client.GetTokenByClientCredentialsInput) (*oidc.TokenSet, error)) *MockInterface_GetTokenByClientCredentials_Call {
_c.Call.Return(run)
return _c
}
// GetTokenByROPC provides a mock function for the type MockInterface
func (_mock *MockInterface) GetTokenByROPC(ctx context.Context, username string, password string) (*oidc.TokenSet, error) {
ret := _mock.Called(ctx, username, password)
if len(ret) == 0 {
panic("no return value specified for GetTokenByROPC")
}
var r0 *oidc.TokenSet
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) (*oidc.TokenSet, error)); ok {
return returnFunc(ctx, username, password)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) *oidc.TokenSet); ok {
r0 = returnFunc(ctx, username, password)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = returnFunc(ctx, username, password)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetTokenByROPC_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenByROPC'
type MockInterface_GetTokenByROPC_Call struct {
*mock.Call
}
// GetTokenByROPC is a helper method to define mock.On call
// - ctx context.Context
// - username string
// - password string
func (_e *MockInterface_Expecter) GetTokenByROPC(ctx interface{}, username interface{}, password interface{}) *MockInterface_GetTokenByROPC_Call {
return &MockInterface_GetTokenByROPC_Call{Call: _e.mock.On("GetTokenByROPC", ctx, username, password)}
}
func (_c *MockInterface_GetTokenByROPC_Call) Run(run func(ctx context.Context, username string, password string)) *MockInterface_GetTokenByROPC_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 string
if args[1] != nil {
arg1 = args[1].(string)
}
var arg2 string
if args[2] != nil {
arg2 = args[2].(string)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockInterface_GetTokenByROPC_Call) Return(tokenSet *oidc.TokenSet, err error) *MockInterface_GetTokenByROPC_Call {
_c.Call.Return(tokenSet, err)
return _c
}
func (_c *MockInterface_GetTokenByROPC_Call) RunAndReturn(run func(ctx context.Context, username string, password string) (*oidc.TokenSet, error)) *MockInterface_GetTokenByROPC_Call {
_c.Call.Return(run)
return _c
}
// NegotiatedPKCEMethod provides a mock function for the type MockInterface
func (_mock *MockInterface) NegotiatedPKCEMethod() pkce.Method {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for NegotiatedPKCEMethod")
}
var r0 pkce.Method
if returnFunc, ok := ret.Get(0).(func() pkce.Method); ok {
r0 = returnFunc()
} else {
r0 = ret.Get(0).(pkce.Method)
}
return r0
}
// MockInterface_NegotiatedPKCEMethod_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NegotiatedPKCEMethod'
type MockInterface_NegotiatedPKCEMethod_Call struct {
*mock.Call
}
// NegotiatedPKCEMethod is a helper method to define mock.On call
func (_e *MockInterface_Expecter) NegotiatedPKCEMethod() *MockInterface_NegotiatedPKCEMethod_Call {
return &MockInterface_NegotiatedPKCEMethod_Call{Call: _e.mock.On("NegotiatedPKCEMethod")}
}
func (_c *MockInterface_NegotiatedPKCEMethod_Call) Run(run func()) *MockInterface_NegotiatedPKCEMethod_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockInterface_NegotiatedPKCEMethod_Call) Return(method pkce.Method) *MockInterface_NegotiatedPKCEMethod_Call {
_c.Call.Return(method)
return _c
}
func (_c *MockInterface_NegotiatedPKCEMethod_Call) RunAndReturn(run func() pkce.Method) *MockInterface_NegotiatedPKCEMethod_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function for the type MockInterface
func (_mock *MockInterface) Refresh(ctx context.Context, refreshToken string) (*oidc.TokenSet, error) {
ret := _mock.Called(ctx, refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *oidc.TokenSet
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*oidc.TokenSet, error)); ok {
return returnFunc(ctx, refreshToken)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, string) *oidc.TokenSet); ok {
r0 = returnFunc(ctx, refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = returnFunc(ctx, refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockInterface_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - ctx context.Context
// - refreshToken string
func (_e *MockInterface_Expecter) Refresh(ctx interface{}, refreshToken interface{}) *MockInterface_Refresh_Call {
return &MockInterface_Refresh_Call{Call: _e.mock.On("Refresh", ctx, refreshToken)}
}
func (_c *MockInterface_Refresh_Call) Run(run func(ctx context.Context, refreshToken string)) *MockInterface_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 string
if args[1] != nil {
arg1 = args[1].(string)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_Refresh_Call) Return(tokenSet *oidc.TokenSet, err error) *MockInterface_Refresh_Call {
_c.Call.Return(tokenSet, err)
return _c
}
func (_c *MockInterface_Refresh_Call) RunAndReturn(run func(ctx context.Context, refreshToken string) (*oidc.TokenSet, error)) *MockInterface_Refresh_Call {
_c.Call.Return(run)
return _c
}
// NewMockFactoryInterface creates a new instance of MockFactoryInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockFactoryInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockFactoryInterface {
mock := &MockFactoryInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockFactoryInterface is an autogenerated mock type for the FactoryInterface type
type MockFactoryInterface struct {
mock.Mock
}
type MockFactoryInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockFactoryInterface) EXPECT() *MockFactoryInterface_Expecter {
return &MockFactoryInterface_Expecter{mock: &_m.Mock}
}
// New provides a mock function for the type MockFactoryInterface
func (_mock *MockFactoryInterface) New(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config) (client.Interface, error) {
ret := _mock.Called(ctx, prov, tlsClientConfig)
if len(ret) == 0 {
panic("no return value specified for New")
}
var r0 client.Interface
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, oidc.Provider, tlsclientconfig.Config) (client.Interface, error)); ok {
return returnFunc(ctx, prov, tlsClientConfig)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, oidc.Provider, tlsclientconfig.Config) client.Interface); ok {
r0 = returnFunc(ctx, prov, tlsClientConfig)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(client.Interface)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, oidc.Provider, tlsclientconfig.Config) error); ok {
r1 = returnFunc(ctx, prov, tlsClientConfig)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockFactoryInterface_New_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'New'
type MockFactoryInterface_New_Call struct {
*mock.Call
}
// New is a helper method to define mock.On call
// - ctx context.Context
// - prov oidc.Provider
// - tlsClientConfig tlsclientconfig.Config
func (_e *MockFactoryInterface_Expecter) New(ctx interface{}, prov interface{}, tlsClientConfig interface{}) *MockFactoryInterface_New_Call {
return &MockFactoryInterface_New_Call{Call: _e.mock.On("New", ctx, prov, tlsClientConfig)}
}
func (_c *MockFactoryInterface_New_Call) Run(run func(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config)) *MockFactoryInterface_New_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 oidc.Provider
if args[1] != nil {
arg1 = args[1].(oidc.Provider)
}
var arg2 tlsclientconfig.Config
if args[2] != nil {
arg2 = args[2].(tlsclientconfig.Config)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockFactoryInterface_New_Call) Return(interfaceParam client.Interface, err error) *MockFactoryInterface_New_Call {
_c.Call.Return(interfaceParam, err)
return _c
}
func (_c *MockFactoryInterface_New_Call) RunAndReturn(run func(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config) (client.Interface, error)) *MockFactoryInterface_New_Call {
_c.Call.Return(run)
return _c
}

View File

@@ -1,76 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package logger_mock
import mock "github.com/stretchr/testify/mock"
// MocktestingLogger is an autogenerated mock type for the testingLogger type
type MocktestingLogger struct {
mock.Mock
}
type MocktestingLogger_Expecter struct {
mock *mock.Mock
}
func (_m *MocktestingLogger) EXPECT() *MocktestingLogger_Expecter {
return &MocktestingLogger_Expecter{mock: &_m.Mock}
}
// Logf provides a mock function with given fields: format, v
func (_m *MocktestingLogger) Logf(format string, v ...interface{}) {
var _ca []interface{}
_ca = append(_ca, format)
_ca = append(_ca, v...)
_m.Called(_ca...)
}
// MocktestingLogger_Logf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Logf'
type MocktestingLogger_Logf_Call struct {
*mock.Call
}
// Logf is a helper method to define mock.On call
// - format string
// - v ...interface{}
func (_e *MocktestingLogger_Expecter) Logf(format interface{}, v ...interface{}) *MocktestingLogger_Logf_Call {
return &MocktestingLogger_Logf_Call{Call: _e.mock.On("Logf",
append([]interface{}{format}, v...)...)}
}
func (_c *MocktestingLogger_Logf_Call) Run(run func(format string, v ...interface{})) *MocktestingLogger_Logf_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]interface{}, len(args)-1)
for i, a := range args[1:] {
if a != nil {
variadicArgs[i] = a.(interface{})
}
}
run(args[0].(string), variadicArgs...)
})
return _c
}
func (_c *MocktestingLogger_Logf_Call) Return() *MocktestingLogger_Logf_Call {
_c.Call.Return()
return _c
}
func (_c *MocktestingLogger_Logf_Call) RunAndReturn(run func(string, ...interface{})) *MocktestingLogger_Logf_Call {
_c.Run(run)
return _c
}
// NewMocktestingLogger creates a new instance of MocktestingLogger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMocktestingLogger(t interface {
mock.TestingT
Cleanup(func())
}) *MocktestingLogger {
mock := &MocktestingLogger{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,90 @@
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package logger_mock
import (
mock "github.com/stretchr/testify/mock"
)
// newMocktestingLogger creates a new instance of mocktestingLogger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func newMocktestingLogger(t interface {
mock.TestingT
Cleanup(func())
}) *mocktestingLogger {
mock := &mocktestingLogger{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// mocktestingLogger is an autogenerated mock type for the testingLogger type
type mocktestingLogger struct {
mock.Mock
}
type mocktestingLogger_Expecter struct {
mock *mock.Mock
}
func (_m *mocktestingLogger) EXPECT() *mocktestingLogger_Expecter {
return &mocktestingLogger_Expecter{mock: &_m.Mock}
}
// Logf provides a mock function for the type mocktestingLogger
func (_mock *mocktestingLogger) Logf(format string, v ...interface{}) {
if len(v) > 0 {
_mock.Called(format, v)
} else {
_mock.Called(format)
}
return
}
// mocktestingLogger_Logf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Logf'
type mocktestingLogger_Logf_Call struct {
*mock.Call
}
// Logf is a helper method to define mock.On call
// - format string
// - v ...interface{}
func (_e *mocktestingLogger_Expecter) Logf(format interface{}, v ...interface{}) *mocktestingLogger_Logf_Call {
return &mocktestingLogger_Logf_Call{Call: _e.mock.On("Logf",
append([]interface{}{format}, v...)...)}
}
func (_c *mocktestingLogger_Logf_Call) Run(run func(format string, v ...interface{})) *mocktestingLogger_Logf_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 string
if args[0] != nil {
arg0 = args[0].(string)
}
var arg1 []interface{}
var variadicArgs []interface{}
if len(args) > 1 {
variadicArgs = args[1].([]interface{})
}
arg1 = variadicArgs
run(
arg0,
arg1...,
)
})
return _c
}
func (_c *mocktestingLogger_Logf_Call) Return() *mocktestingLogger_Logf_Call {
_c.Call.Return()
return _c
}
func (_c *mocktestingLogger_Logf_Call) RunAndReturn(run func(format string, v ...interface{})) *mocktestingLogger_Logf_Call {
_c.Run(run)
return _c
}

View File

@@ -1,15 +1,30 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package loader_mock
import (
tls "crypto/tls"
"crypto/tls"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
mock "github.com/stretchr/testify/mock"
tlsclientconfig "github.com/int128/kubelogin/pkg/tlsclientconfig"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -23,9 +38,9 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Load provides a mock function with given fields: config
func (_m *MockInterface) Load(config tlsclientconfig.Config) (*tls.Config, error) {
ret := _m.Called(config)
// Load provides a mock function for the type MockInterface
func (_mock *MockInterface) Load(config tlsclientconfig.Config) (*tls.Config, error) {
ret := _mock.Called(config)
if len(ret) == 0 {
panic("no return value specified for Load")
@@ -33,23 +48,21 @@ func (_m *MockInterface) Load(config tlsclientconfig.Config) (*tls.Config, error
var r0 *tls.Config
var r1 error
if rf, ok := ret.Get(0).(func(tlsclientconfig.Config) (*tls.Config, error)); ok {
return rf(config)
if returnFunc, ok := ret.Get(0).(func(tlsclientconfig.Config) (*tls.Config, error)); ok {
return returnFunc(config)
}
if rf, ok := ret.Get(0).(func(tlsclientconfig.Config) *tls.Config); ok {
r0 = rf(config)
if returnFunc, ok := ret.Get(0).(func(tlsclientconfig.Config) *tls.Config); ok {
r0 = returnFunc(config)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*tls.Config)
}
}
if rf, ok := ret.Get(1).(func(tlsclientconfig.Config) error); ok {
r1 = rf(config)
if returnFunc, ok := ret.Get(1).(func(tlsclientconfig.Config) error); ok {
r1 = returnFunc(config)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
@@ -66,31 +79,23 @@ func (_e *MockInterface_Expecter) Load(config interface{}) *MockInterface_Load_C
func (_c *MockInterface_Load_Call) Run(run func(config tlsclientconfig.Config)) *MockInterface_Load_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(tlsclientconfig.Config))
var arg0 tlsclientconfig.Config
if args[0] != nil {
arg0 = args[0].(tlsclientconfig.Config)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_Load_Call) Return(_a0 *tls.Config, _a1 error) *MockInterface_Load_Call {
_c.Call.Return(_a0, _a1)
func (_c *MockInterface_Load_Call) Return(config1 *tls.Config, err error) *MockInterface_Load_Call {
_c.Call.Return(config1, err)
return _c
}
func (_c *MockInterface_Load_Call) RunAndReturn(run func(tlsclientconfig.Config) (*tls.Config, error)) *MockInterface_Load_Call {
func (_c *MockInterface_Load_Call) RunAndReturn(run func(config tlsclientconfig.Config) (*tls.Config, error)) *MockInterface_Load_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,205 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package repository_mock
import (
io "io"
oidc "github.com/int128/kubelogin/pkg/oidc"
mock "github.com/stretchr/testify/mock"
tokencache "github.com/int128/kubelogin/pkg/tokencache"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// FindByKey provides a mock function with given fields: dir, key
func (_m *MockInterface) FindByKey(dir string, key tokencache.Key) (*oidc.TokenSet, error) {
ret := _m.Called(dir, key)
if len(ret) == 0 {
panic("no return value specified for FindByKey")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(string, tokencache.Key) (*oidc.TokenSet, error)); ok {
return rf(dir, key)
}
if rf, ok := ret.Get(0).(func(string, tokencache.Key) *oidc.TokenSet); ok {
r0 = rf(dir, key)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(string, tokencache.Key) error); ok {
r1 = rf(dir, key)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_FindByKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByKey'
type MockInterface_FindByKey_Call struct {
*mock.Call
}
// FindByKey is a helper method to define mock.On call
// - dir string
// - key tokencache.Key
func (_e *MockInterface_Expecter) FindByKey(dir interface{}, key interface{}) *MockInterface_FindByKey_Call {
return &MockInterface_FindByKey_Call{Call: _e.mock.On("FindByKey", dir, key)}
}
func (_c *MockInterface_FindByKey_Call) Run(run func(dir string, key tokencache.Key)) *MockInterface_FindByKey_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(tokencache.Key))
})
return _c
}
func (_c *MockInterface_FindByKey_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_FindByKey_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_FindByKey_Call) RunAndReturn(run func(string, tokencache.Key) (*oidc.TokenSet, error)) *MockInterface_FindByKey_Call {
_c.Call.Return(run)
return _c
}
// Lock provides a mock function with given fields: dir, key
func (_m *MockInterface) Lock(dir string, key tokencache.Key) (io.Closer, error) {
ret := _m.Called(dir, key)
if len(ret) == 0 {
panic("no return value specified for Lock")
}
var r0 io.Closer
var r1 error
if rf, ok := ret.Get(0).(func(string, tokencache.Key) (io.Closer, error)); ok {
return rf(dir, key)
}
if rf, ok := ret.Get(0).(func(string, tokencache.Key) io.Closer); ok {
r0 = rf(dir, key)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(io.Closer)
}
}
if rf, ok := ret.Get(1).(func(string, tokencache.Key) error); ok {
r1 = rf(dir, key)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Lock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Lock'
type MockInterface_Lock_Call struct {
*mock.Call
}
// Lock is a helper method to define mock.On call
// - dir string
// - key tokencache.Key
func (_e *MockInterface_Expecter) Lock(dir interface{}, key interface{}) *MockInterface_Lock_Call {
return &MockInterface_Lock_Call{Call: _e.mock.On("Lock", dir, key)}
}
func (_c *MockInterface_Lock_Call) Run(run func(dir string, key tokencache.Key)) *MockInterface_Lock_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(tokencache.Key))
})
return _c
}
func (_c *MockInterface_Lock_Call) Return(_a0 io.Closer, _a1 error) *MockInterface_Lock_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_Lock_Call) RunAndReturn(run func(string, tokencache.Key) (io.Closer, error)) *MockInterface_Lock_Call {
_c.Call.Return(run)
return _c
}
// Save provides a mock function with given fields: dir, key, tokenSet
func (_m *MockInterface) Save(dir string, key tokencache.Key, tokenSet oidc.TokenSet) error {
ret := _m.Called(dir, key, tokenSet)
if len(ret) == 0 {
panic("no return value specified for Save")
}
var r0 error
if rf, ok := ret.Get(0).(func(string, tokencache.Key, oidc.TokenSet) error); ok {
r0 = rf(dir, key, tokenSet)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Save_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Save'
type MockInterface_Save_Call struct {
*mock.Call
}
// Save is a helper method to define mock.On call
// - dir string
// - key tokencache.Key
// - tokenSet oidc.TokenSet
func (_e *MockInterface_Expecter) Save(dir interface{}, key interface{}, tokenSet interface{}) *MockInterface_Save_Call {
return &MockInterface_Save_Call{Call: _e.mock.On("Save", dir, key, tokenSet)}
}
func (_c *MockInterface_Save_Call) Run(run func(dir string, key tokencache.Key, tokenSet oidc.TokenSet)) *MockInterface_Save_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(tokencache.Key), args[2].(oidc.TokenSet))
})
return _c
}
func (_c *MockInterface_Save_Call) Return(_a0 error) *MockInterface_Save_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Save_Call) RunAndReturn(run func(string, tokencache.Key, oidc.TokenSet) error) *MockInterface_Save_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,290 @@
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package repository_mock
import (
"io"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/tokencache"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// DeleteAll provides a mock function for the type MockInterface
func (_mock *MockInterface) DeleteAll(config tokencache.Config) error {
ret := _mock.Called(config)
if len(ret) == 0 {
panic("no return value specified for DeleteAll")
}
var r0 error
if returnFunc, ok := ret.Get(0).(func(tokencache.Config) error); ok {
r0 = returnFunc(config)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_DeleteAll_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteAll'
type MockInterface_DeleteAll_Call struct {
*mock.Call
}
// DeleteAll is a helper method to define mock.On call
// - config tokencache.Config
func (_e *MockInterface_Expecter) DeleteAll(config interface{}) *MockInterface_DeleteAll_Call {
return &MockInterface_DeleteAll_Call{Call: _e.mock.On("DeleteAll", config)}
}
func (_c *MockInterface_DeleteAll_Call) Run(run func(config tokencache.Config)) *MockInterface_DeleteAll_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 tokencache.Config
if args[0] != nil {
arg0 = args[0].(tokencache.Config)
}
run(
arg0,
)
})
return _c
}
func (_c *MockInterface_DeleteAll_Call) Return(err error) *MockInterface_DeleteAll_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_DeleteAll_Call) RunAndReturn(run func(config tokencache.Config) error) *MockInterface_DeleteAll_Call {
_c.Call.Return(run)
return _c
}
// FindByKey provides a mock function for the type MockInterface
func (_mock *MockInterface) FindByKey(config tokencache.Config, key tokencache.Key) (*oidc.TokenSet, error) {
ret := _mock.Called(config, key)
if len(ret) == 0 {
panic("no return value specified for FindByKey")
}
var r0 *oidc.TokenSet
var r1 error
if returnFunc, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key) (*oidc.TokenSet, error)); ok {
return returnFunc(config, key)
}
if returnFunc, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key) *oidc.TokenSet); ok {
r0 = returnFunc(config, key)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if returnFunc, ok := ret.Get(1).(func(tokencache.Config, tokencache.Key) error); ok {
r1 = returnFunc(config, key)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_FindByKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByKey'
type MockInterface_FindByKey_Call struct {
*mock.Call
}
// FindByKey is a helper method to define mock.On call
// - config tokencache.Config
// - key tokencache.Key
func (_e *MockInterface_Expecter) FindByKey(config interface{}, key interface{}) *MockInterface_FindByKey_Call {
return &MockInterface_FindByKey_Call{Call: _e.mock.On("FindByKey", config, key)}
}
func (_c *MockInterface_FindByKey_Call) Run(run func(config tokencache.Config, key tokencache.Key)) *MockInterface_FindByKey_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 tokencache.Config
if args[0] != nil {
arg0 = args[0].(tokencache.Config)
}
var arg1 tokencache.Key
if args[1] != nil {
arg1 = args[1].(tokencache.Key)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_FindByKey_Call) Return(tokenSet *oidc.TokenSet, err error) *MockInterface_FindByKey_Call {
_c.Call.Return(tokenSet, err)
return _c
}
func (_c *MockInterface_FindByKey_Call) RunAndReturn(run func(config tokencache.Config, key tokencache.Key) (*oidc.TokenSet, error)) *MockInterface_FindByKey_Call {
_c.Call.Return(run)
return _c
}
// Lock provides a mock function for the type MockInterface
func (_mock *MockInterface) Lock(config tokencache.Config, key tokencache.Key) (io.Closer, error) {
ret := _mock.Called(config, key)
if len(ret) == 0 {
panic("no return value specified for Lock")
}
var r0 io.Closer
var r1 error
if returnFunc, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key) (io.Closer, error)); ok {
return returnFunc(config, key)
}
if returnFunc, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key) io.Closer); ok {
r0 = returnFunc(config, key)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(io.Closer)
}
}
if returnFunc, ok := ret.Get(1).(func(tokencache.Config, tokencache.Key) error); ok {
r1 = returnFunc(config, key)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Lock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Lock'
type MockInterface_Lock_Call struct {
*mock.Call
}
// Lock is a helper method to define mock.On call
// - config tokencache.Config
// - key tokencache.Key
func (_e *MockInterface_Expecter) Lock(config interface{}, key interface{}) *MockInterface_Lock_Call {
return &MockInterface_Lock_Call{Call: _e.mock.On("Lock", config, key)}
}
func (_c *MockInterface_Lock_Call) Run(run func(config tokencache.Config, key tokencache.Key)) *MockInterface_Lock_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 tokencache.Config
if args[0] != nil {
arg0 = args[0].(tokencache.Config)
}
var arg1 tokencache.Key
if args[1] != nil {
arg1 = args[1].(tokencache.Key)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_Lock_Call) Return(closer io.Closer, err error) *MockInterface_Lock_Call {
_c.Call.Return(closer, err)
return _c
}
func (_c *MockInterface_Lock_Call) RunAndReturn(run func(config tokencache.Config, key tokencache.Key) (io.Closer, error)) *MockInterface_Lock_Call {
_c.Call.Return(run)
return _c
}
// Save provides a mock function for the type MockInterface
func (_mock *MockInterface) Save(config tokencache.Config, key tokencache.Key, tokenSet oidc.TokenSet) error {
ret := _mock.Called(config, key, tokenSet)
if len(ret) == 0 {
panic("no return value specified for Save")
}
var r0 error
if returnFunc, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key, oidc.TokenSet) error); ok {
r0 = returnFunc(config, key, tokenSet)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Save_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Save'
type MockInterface_Save_Call struct {
*mock.Call
}
// Save is a helper method to define mock.On call
// - config tokencache.Config
// - key tokencache.Key
// - tokenSet oidc.TokenSet
func (_e *MockInterface_Expecter) Save(config interface{}, key interface{}, tokenSet interface{}) *MockInterface_Save_Call {
return &MockInterface_Save_Call{Call: _e.mock.On("Save", config, key, tokenSet)}
}
func (_c *MockInterface_Save_Call) Run(run func(config tokencache.Config, key tokencache.Key, tokenSet oidc.TokenSet)) *MockInterface_Save_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 tokencache.Config
if args[0] != nil {
arg0 = args[0].(tokencache.Config)
}
var arg1 tokencache.Key
if args[1] != nil {
arg1 = args[1].(tokencache.Key)
}
var arg2 oidc.TokenSet
if args[2] != nil {
arg2 = args[2].(oidc.TokenSet)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *MockInterface_Save_Call) Return(err error) *MockInterface_Save_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_Save_Call) RunAndReturn(run func(config tokencache.Config, key tokencache.Key, tokenSet oidc.TokenSet) error) *MockInterface_Save_Call {
_c.Call.Return(run)
return _c
}

View File

@@ -1,15 +1,30 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package authentication_mock
import (
context "context"
authentication "github.com/int128/kubelogin/pkg/usecases/authentication"
"context"
"github.com/int128/kubelogin/pkg/usecases/authentication"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -23,9 +38,9 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function with given fields: ctx, in
func (_m *MockInterface) Do(ctx context.Context, in authentication.Input) (*authentication.Output, error) {
ret := _m.Called(ctx, in)
// Do provides a mock function for the type MockInterface
func (_mock *MockInterface) Do(ctx context.Context, in authentication.Input) (*authentication.Output, error) {
ret := _mock.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
@@ -33,23 +48,21 @@ func (_m *MockInterface) Do(ctx context.Context, in authentication.Input) (*auth
var r0 *authentication.Output
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, authentication.Input) (*authentication.Output, error)); ok {
return rf(ctx, in)
if returnFunc, ok := ret.Get(0).(func(context.Context, authentication.Input) (*authentication.Output, error)); ok {
return returnFunc(ctx, in)
}
if rf, ok := ret.Get(0).(func(context.Context, authentication.Input) *authentication.Output); ok {
r0 = rf(ctx, in)
if returnFunc, ok := ret.Get(0).(func(context.Context, authentication.Input) *authentication.Output); ok {
r0 = returnFunc(ctx, in)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*authentication.Output)
}
}
if rf, ok := ret.Get(1).(func(context.Context, authentication.Input) error); ok {
r1 = rf(ctx, in)
if returnFunc, ok := ret.Get(1).(func(context.Context, authentication.Input) error); ok {
r1 = returnFunc(ctx, in)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
@@ -67,31 +80,28 @@ func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInter
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in authentication.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(authentication.Input))
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 authentication.Input
if args[1] != nil {
arg1 = args[1].(authentication.Input)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_Do_Call) Return(_a0 *authentication.Output, _a1 error) *MockInterface_Do_Call {
_c.Call.Return(_a0, _a1)
func (_c *MockInterface_Do_Call) Return(output *authentication.Output, err error) *MockInterface_Do_Call {
_c.Call.Return(output, err)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(context.Context, authentication.Input) (*authentication.Output, error)) *MockInterface_Do_Call {
func (_c *MockInterface_Do_Call) RunAndReturn(run func(ctx context.Context, in authentication.Input) (*authentication.Output, error)) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,96 @@
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package clean_mock
import (
"context"
"github.com/int128/kubelogin/pkg/usecases/clean"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function for the type MockInterface
func (_mock *MockInterface) Do(ctx context.Context, in clean.Input) error {
ret := _mock.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
}
var r0 error
if returnFunc, ok := ret.Get(0).(func(context.Context, clean.Input) error); ok {
r0 = returnFunc(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Do_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Do'
type MockInterface_Do_Call struct {
*mock.Call
}
// Do is a helper method to define mock.On call
// - ctx context.Context
// - in clean.Input
func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInterface_Do_Call {
return &MockInterface_Do_Call{Call: _e.mock.On("Do", ctx, in)}
}
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in clean.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 clean.Input
if args[1] != nil {
arg1 = args[1].(clean.Input)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_Do_Call) Return(err error) *MockInterface_Do_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(ctx context.Context, in clean.Input) error) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}

View File

@@ -1,14 +1,30 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package credentialplugin_mock
import (
context "context"
"context"
credentialplugin "github.com/int128/kubelogin/pkg/usecases/credentialplugin"
"github.com/int128/kubelogin/pkg/usecases/credentialplugin"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -22,21 +38,20 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function with given fields: ctx, in
func (_m *MockInterface) Do(ctx context.Context, in credentialplugin.Input) error {
ret := _m.Called(ctx, in)
// Do provides a mock function for the type MockInterface
func (_mock *MockInterface) Do(ctx context.Context, in credentialplugin.Input) error {
ret := _mock.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, credentialplugin.Input) error); ok {
r0 = rf(ctx, in)
if returnFunc, ok := ret.Get(0).(func(context.Context, credentialplugin.Input) error); ok {
r0 = returnFunc(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
@@ -54,31 +69,28 @@ func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInter
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in credentialplugin.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(credentialplugin.Input))
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 credentialplugin.Input
if args[1] != nil {
arg1 = args[1].(credentialplugin.Input)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_Do_Call) Return(_a0 error) *MockInterface_Do_Call {
_c.Call.Return(_a0)
func (_c *MockInterface_Do_Call) Return(err error) *MockInterface_Do_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(context.Context, credentialplugin.Input) error) *MockInterface_Do_Call {
func (_c *MockInterface_Do_Call) RunAndReturn(run func(ctx context.Context, in credentialplugin.Input) error) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,116 +0,0 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
package setup_mock
import (
context "context"
setup "github.com/int128/kubelogin/pkg/usecases/setup"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// DoStage1 provides a mock function with no fields
func (_m *MockInterface) DoStage1() {
_m.Called()
}
// MockInterface_DoStage1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DoStage1'
type MockInterface_DoStage1_Call struct {
*mock.Call
}
// DoStage1 is a helper method to define mock.On call
func (_e *MockInterface_Expecter) DoStage1() *MockInterface_DoStage1_Call {
return &MockInterface_DoStage1_Call{Call: _e.mock.On("DoStage1")}
}
func (_c *MockInterface_DoStage1_Call) Run(run func()) *MockInterface_DoStage1_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockInterface_DoStage1_Call) Return() *MockInterface_DoStage1_Call {
_c.Call.Return()
return _c
}
func (_c *MockInterface_DoStage1_Call) RunAndReturn(run func()) *MockInterface_DoStage1_Call {
_c.Run(run)
return _c
}
// DoStage2 provides a mock function with given fields: ctx, in
func (_m *MockInterface) DoStage2(ctx context.Context, in setup.Stage2Input) error {
ret := _m.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for DoStage2")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, setup.Stage2Input) error); ok {
r0 = rf(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_DoStage2_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DoStage2'
type MockInterface_DoStage2_Call struct {
*mock.Call
}
// DoStage2 is a helper method to define mock.On call
// - ctx context.Context
// - in setup.Stage2Input
func (_e *MockInterface_Expecter) DoStage2(ctx interface{}, in interface{}) *MockInterface_DoStage2_Call {
return &MockInterface_DoStage2_Call{Call: _e.mock.On("DoStage2", ctx, in)}
}
func (_c *MockInterface_DoStage2_Call) Run(run func(ctx context.Context, in setup.Stage2Input)) *MockInterface_DoStage2_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(setup.Stage2Input))
})
return _c
}
func (_c *MockInterface_DoStage2_Call) Return(_a0 error) *MockInterface_DoStage2_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_DoStage2_Call) RunAndReturn(run func(context.Context, setup.Stage2Input) error) *MockInterface_DoStage2_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,96 @@
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package setup_mock
import (
"context"
"github.com/int128/kubelogin/pkg/usecases/setup"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function for the type MockInterface
func (_mock *MockInterface) Do(ctx context.Context, in setup.Input) error {
ret := _mock.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
}
var r0 error
if returnFunc, ok := ret.Get(0).(func(context.Context, setup.Input) error); ok {
r0 = returnFunc(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Do_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Do'
type MockInterface_Do_Call struct {
*mock.Call
}
// Do is a helper method to define mock.On call
// - ctx context.Context
// - in setup.Input
func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInterface_Do_Call {
return &MockInterface_Do_Call{Call: _e.mock.On("Do", ctx, in)}
}
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in setup.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 setup.Input
if args[1] != nil {
arg1 = args[1].(setup.Input)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_Do_Call) Return(err error) *MockInterface_Do_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(ctx context.Context, in setup.Input) error) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}

View File

@@ -1,14 +1,30 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package standalone_mock
import (
context "context"
"context"
standalone "github.com/int128/kubelogin/pkg/usecases/standalone"
"github.com/int128/kubelogin/pkg/usecases/standalone"
mock "github.com/stretchr/testify/mock"
)
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
@@ -22,21 +38,20 @@ func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function with given fields: ctx, in
func (_m *MockInterface) Do(ctx context.Context, in standalone.Input) error {
ret := _m.Called(ctx, in)
// Do provides a mock function for the type MockInterface
func (_mock *MockInterface) Do(ctx context.Context, in standalone.Input) error {
ret := _mock.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, standalone.Input) error); ok {
r0 = rf(ctx, in)
if returnFunc, ok := ret.Get(0).(func(context.Context, standalone.Input) error); ok {
r0 = returnFunc(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
@@ -54,31 +69,28 @@ func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInter
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in standalone.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(standalone.Input))
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 standalone.Input
if args[1] != nil {
arg1 = args[1].(standalone.Input)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *MockInterface_Do_Call) Return(_a0 error) *MockInterface_Do_Call {
_c.Call.Return(_a0)
func (_c *MockInterface_Do_Call) Return(err error) *MockInterface_Do_Call {
_c.Call.Return(err)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(context.Context, standalone.Input) error) *MockInterface_Do_Call {
func (_c *MockInterface_Do_Call) RunAndReturn(run func(ctx context.Context, in standalone.Input) error) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -1,8 +1,26 @@
// Code generated by mockery v2.50.4. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package io_mock
import mock "github.com/stretchr/testify/mock"
import (
mock "github.com/stretchr/testify/mock"
)
// NewMockCloser creates a new instance of MockCloser. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockCloser(t interface {
mock.TestingT
Cleanup(func())
}) *MockCloser {
mock := &MockCloser{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
// MockCloser is an autogenerated mock type for the Closer type
type MockCloser struct {
@@ -17,21 +35,20 @@ func (_m *MockCloser) EXPECT() *MockCloser_Expecter {
return &MockCloser_Expecter{mock: &_m.Mock}
}
// Close provides a mock function with no fields
func (_m *MockCloser) Close() error {
ret := _m.Called()
// Close provides a mock function for the type MockCloser
func (_mock *MockCloser) Close() error {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for Close")
}
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
if returnFunc, ok := ret.Get(0).(func() error); ok {
r0 = returnFunc()
} else {
r0 = ret.Error(0)
}
return r0
}
@@ -52,8 +69,8 @@ func (_c *MockCloser_Close_Call) Run(run func()) *MockCloser_Close_Call {
return _c
}
func (_c *MockCloser_Close_Call) Return(_a0 error) *MockCloser_Close_Call {
_c.Call.Return(_a0)
func (_c *MockCloser_Close_Call) Return(err error) *MockCloser_Close_Call {
_c.Call.Return(err)
return _c
}
@@ -61,17 +78,3 @@ func (_c *MockCloser_Close_Call) RunAndReturn(run func() error) *MockCloser_Clos
_c.Call.Return(run)
return _c
}
// NewMockCloser creates a new instance of MockCloser. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockCloser(t interface {
mock.TestingT
Cleanup(func())
}) *MockCloser {
mock := &MockCloser{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -5,15 +5,15 @@ import (
"strings"
"time"
"github.com/spf13/pflag"
"github.com/int128/kubelogin/pkg/oidc/client"
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/authentication/devicecode"
"github.com/int128/kubelogin/pkg/usecases/authentication/ropc"
"github.com/spf13/pflag"
)
const oobRedirectURI = "urn:ietf:wg:oauth:2.0:oob"
type authenticationOptions struct {
GrantType string
ListenAddress []string
@@ -23,8 +23,8 @@ type authenticationOptions struct {
LocalServerCertFile string
LocalServerKeyFile string
OpenURLAfterAuthentication string
RedirectURLHostname string
RedirectURLAuthCodeKeyboard string
RedirectURLHostname string // DEPRECATED
RedirectURLAuthCodeKeyboard string // DEPRECATED
AuthRequestExtraParams map[string]string
Username string
Password string
@@ -36,6 +36,7 @@ var allGrantType = strings.Join([]string{
"authcode-keyboard",
"password",
"device-code",
"client-credentials",
}, "|")
func (o *authenticationOptions) addFlags(f *pflag.FlagSet) {
@@ -47,9 +48,15 @@ func (o *authenticationOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.LocalServerCertFile, "local-server-cert", "", "[authcode] Certificate path for the local server")
f.StringVar(&o.LocalServerKeyFile, "local-server-key", "", "[authcode] Certificate key path for the local server")
f.StringVar(&o.OpenURLAfterAuthentication, "open-url-after-authentication", "", "[authcode] If set, open the URL in the browser after authentication")
f.StringVar(&o.RedirectURLHostname, "oidc-redirect-url-hostname", "localhost", "[authcode] Hostname of the redirect URL")
f.StringVar(&o.RedirectURLAuthCodeKeyboard, "oidc-redirect-url-authcode-keyboard", oobRedirectURI, "[authcode-keyboard] Redirect URL")
f.StringToStringVar(&o.AuthRequestExtraParams, "oidc-auth-request-extra-params", nil, "[authcode, authcode-keyboard] Extra query parameters to send with an authentication request")
f.StringVar(&o.RedirectURLHostname, "oidc-redirect-url-hostname", "", "[authcode] Hostname of the redirect URL")
if err := f.MarkDeprecated("oidc-redirect-url-hostname", "use --oidc-redirect-url instead."); err != nil {
panic(err)
}
f.StringVar(&o.RedirectURLAuthCodeKeyboard, "oidc-redirect-url-authcode-keyboard", "", "Equivalent to --oidc-redirect-url")
if err := f.MarkDeprecated("oidc-redirect-url-authcode-keyboard", "use --oidc-redirect-url instead."); err != nil {
panic(err)
}
f.StringToStringVar(&o.AuthRequestExtraParams, "oidc-auth-request-extra-params", nil, "[authcode, authcode-keyboard, client-credentials] Extra query parameters to send with an authentication request")
f.StringVar(&o.Username, "username", "", "[password] Username for resource owner password credentials grant")
f.StringVar(&o.Password, "password", "", "[password] Password for resource owner password credentials grant")
}
@@ -76,7 +83,6 @@ func (o *authenticationOptions) grantOptionSet() (s authentication.GrantOptionSe
case o.GrantType == "authcode-keyboard":
s.AuthCodeKeyboardOption = &authcode.KeyboardOption{
AuthRequestExtraParams: o.AuthRequestExtraParams,
RedirectURL: o.RedirectURLAuthCodeKeyboard,
}
case o.GrantType == "password" || (o.GrantType == "auto" && o.Username != ""):
s.ROPCOption = &ropc.Option{
@@ -88,6 +94,12 @@ func (o *authenticationOptions) grantOptionSet() (s authentication.GrantOptionSe
SkipOpenBrowser: o.SkipOpenBrowser,
BrowserCommand: o.BrowserCommand,
}
case o.GrantType == "client-credentials":
endpointparams := make(map[string][]string, len(o.AuthRequestExtraParams))
for k, v := range o.AuthRequestExtraParams {
endpointparams[k] = []string{v}
}
s.ClientCredentialsOption = &client.GetTokenByClientCredentialsInput{EndpointParams: endpointparams}
default:
err = fmt.Errorf("grant-type must be one of (%s)", allGrantType)
}

View File

@@ -5,6 +5,7 @@ import (
"time"
"github.com/google/go-cmp/cmp"
"github.com/int128/kubelogin/pkg/oidc/client"
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/authentication/ropc"
@@ -21,7 +22,6 @@ func Test_authenticationOptions_grantOptionSet(t *testing.T) {
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
},
},
},
@@ -61,19 +61,19 @@ func Test_authenticationOptions_grantOptionSet(t *testing.T) {
"--grant-type", "authcode-keyboard",
},
want: authentication.GrantOptionSet{
AuthCodeKeyboardOption: &authcode.KeyboardOption{
RedirectURL: oobRedirectURI,
},
AuthCodeKeyboardOption: &authcode.KeyboardOption{},
},
},
"GrantType=authcode-keyboard with full options": {
args: []string{
"--grant-type", "authcode-keyboard",
"--oidc-redirect-url-authcode-keyboard", "http://localhost",
"--oidc-auth-request-extra-params", "ttl=86400",
"--oidc-auth-request-extra-params", "reauth=true",
},
want: authentication.GrantOptionSet{
AuthCodeKeyboardOption: &authcode.KeyboardOption{
RedirectURL: "http://localhost",
AuthRequestExtraParams: map[string]string{"ttl": "86400", "reauth": "true"},
},
},
},
@@ -92,6 +92,21 @@ func Test_authenticationOptions_grantOptionSet(t *testing.T) {
},
},
},
"GrantType=client-credentials": {
args: []string{
"--grant-type", "client-credentials",
"--oidc-auth-request-extra-params", "audience=https://example.com/service1",
"--oidc-auth-request-extra-params", "jti=myUUID",
},
want: authentication.GrantOptionSet{
ClientCredentialsOption: &client.GetTokenByClientCredentialsInput{
EndpointParams: map[string][]string{
"audience": []string{"https://example.com/service1"},
"jti": []string{"myUUID"},
},
},
},
},
"GrantType=auto": {
args: []string{
"--listen-address", "127.0.0.1:10080",

47
pkg/cmd/clean.go Normal file
View File

@@ -0,0 +1,47 @@
package cmd
import (
"fmt"
"github.com/int128/kubelogin/pkg/usecases/clean"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
type cleanOptions struct {
TokenCacheDir string
}
func (o *cleanOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.TokenCacheDir, "token-cache-dir", getDefaultTokenCacheDir(), "Path to a directory of the token cache")
}
type Clean struct {
Clean clean.Interface
}
func (cmd *Clean) New() *cobra.Command {
var o cleanOptions
c := &cobra.Command{
Use: "clean [flags]",
Short: "Delete the token cache",
Long: `Delete the token cache.
This deletes the token cache directory from both the file system and the keyring.
`,
Args: cobra.NoArgs,
RunE: func(c *cobra.Command, _ []string) error {
o.TokenCacheDir = expandHomedir(o.TokenCacheDir)
in := clean.Input{
TokenCacheDir: o.TokenCacheDir,
}
if err := cmd.Clean.Do(c.Context(), in); err != nil {
return fmt.Errorf("clean: %w", err)
}
return nil
},
}
c.Flags().SortFlags = false
o.addFlags(c.Flags())
return c
}

View File

@@ -2,8 +2,6 @@ package cmd
import (
"context"
"os"
"path/filepath"
"runtime"
"github.com/google/wire"
@@ -18,23 +16,14 @@ var Set = wire.NewSet(
wire.Struct(new(Root), "*"),
wire.Struct(new(GetToken), "*"),
wire.Struct(new(Setup), "*"),
wire.Struct(new(Clean), "*"),
)
type Interface interface {
Run(ctx context.Context, args []string, version string) int
}
func getDefaultTokenCacheDir(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}
var defaultListenAddress = []string{"127.0.0.1:8000", "127.0.0.1:18000"}
var defaultTokenCacheDir = filepath.Join(
getDefaultTokenCacheDir("KUBECACHEDIR", filepath.Join("~", ".kube", "cache")),
"oidc-login")
const defaultAuthenticationTimeoutSec = 180
@@ -43,6 +32,7 @@ type Cmd struct {
Root *Root
GetToken *GetToken
Setup *Setup
Clean *Clean
Logger logger.Interface
}
@@ -60,6 +50,9 @@ func (cmd *Cmd) Run(ctx context.Context, args []string, version string) int {
setupCmd := cmd.Setup.New()
rootCmd.AddCommand(setupCmd)
cleanCmd := cmd.Clean.New()
rootCmd.AddCommand(cleanCmd)
versionCmd := &cobra.Command{
Use: "version",
Short: "Print the version information",

View File

@@ -8,13 +8,16 @@ import (
"time"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/usecases/credentialplugin_mock"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/usecases/setup_mock"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/usecases/standalone_mock"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/testing/logger"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
"github.com/int128/kubelogin/pkg/tokencache"
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/credentialplugin"
"github.com/int128/kubelogin/pkg/usecases/setup"
"github.com/int128/kubelogin/pkg/usecases/standalone"
)
@@ -22,6 +25,13 @@ func TestCmd_Run(t *testing.T) {
const executable = "kubelogin"
const version = "HEAD"
defaultGrantOptionSet := authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
},
}
t.Run("root", func(t *testing.T) {
tests := map[string]struct {
args []string
@@ -30,13 +40,7 @@ func TestCmd_Run(t *testing.T) {
"Defaults": {
args: []string{executable},
in: standalone.Input{
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
},
},
GrantOptionSet: defaultGrantOptionSet,
},
},
"FullOptions": {
@@ -50,13 +54,7 @@ func TestCmd_Run(t *testing.T) {
KubeconfigFilename: "/path/to/kubeconfig",
KubeconfigContext: "hello.k8s.local",
KubeconfigUser: "google",
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
},
},
GrantOptionSet: defaultGrantOptionSet,
},
},
}
@@ -113,18 +111,14 @@ func TestCmd_Run(t *testing.T) {
"--oidc-client-id", "YOUR_CLIENT_ID",
},
in: credentialplugin.Input{
TokenCacheDir: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Provider: oidc.Provider{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT_ID",
},
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
},
TokenCacheConfig: tokencache.Config{
Directory: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
},
GrantOptionSet: defaultGrantOptionSet,
},
},
"FullOptions": {
@@ -135,23 +129,25 @@ func TestCmd_Run(t *testing.T) {
"--oidc-client-secret", "YOUR_CLIENT_SECRET",
"--oidc-extra-scope", "email",
"--oidc-extra-scope", "profile",
"--oidc-request-header", "Origin=localhost:8080",
"--token-cache-storage", "keyring",
"-v1",
},
in: credentialplugin.Input{
TokenCacheDir: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Provider: oidc.Provider{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
ExtraScopes: []string{"email", "profile"},
},
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
RequestHeaders: map[string]string{
"Origin": "localhost:8080",
},
},
TokenCacheConfig: tokencache.Config{
Directory: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Storage: tokencache.StorageKeyring,
},
GrantOptionSet: defaultGrantOptionSet,
},
},
"AccessToken": {
@@ -162,19 +158,15 @@ func TestCmd_Run(t *testing.T) {
"--oidc-use-access-token=true",
},
in: credentialplugin.Input{
TokenCacheDir: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Provider: oidc.Provider{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT_ID",
UseAccessToken: true,
},
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
},
TokenCacheConfig: tokencache.Config{
Directory: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
},
GrantOptionSet: defaultGrantOptionSet,
},
},
"HomedirExpansion": {
@@ -188,16 +180,17 @@ func TestCmd_Run(t *testing.T) {
"--token-cache-dir", "~/.kube/oidc-cache",
},
in: credentialplugin.Input{
TokenCacheDir: filepath.Join(userHomeDir, ".kube/oidc-cache"),
Provider: oidc.Provider{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT_ID",
},
TokenCacheConfig: tokencache.Config{
Directory: filepath.Join(userHomeDir, ".kube/oidc-cache"),
},
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
LocalServerCertFile: filepath.Join(userHomeDir, ".kube/oidc-server.crt"),
LocalServerKeyFile: filepath.Join(userHomeDir, ".kube/oidc-server.key"),
},
@@ -268,4 +261,54 @@ func TestCmd_Run(t *testing.T) {
}
})
})
t.Run("setup", func(t *testing.T) {
t.Run("NoOption", func(t *testing.T) {
ctx := context.TODO()
cmd := Cmd{
Logger: logger.New(t),
Root: &Root{
Logger: logger.New(t),
},
}
exitCode := cmd.Run(ctx, []string{executable, "setup"}, version)
if exitCode != 0 {
t.Errorf("exitCode wants 0 but %d", exitCode)
}
})
t.Run("WithOptions", func(t *testing.T) {
ctx := context.TODO()
setupMock := setup_mock.NewMockInterface(t)
setupMock.EXPECT().Do(ctx, setup.Input{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT",
ExtraScopes: []string{"email", "profile"},
GrantOptionSet: defaultGrantOptionSet,
ChangedFlags: []string{
"--oidc-issuer-url=https://issuer.example.com",
"--oidc-client-id=YOUR_CLIENT",
"--oidc-extra-scope=email",
"--oidc-extra-scope=profile",
},
}).Return(nil)
cmd := Cmd{
Logger: logger.New(t),
Root: &Root{
Logger: logger.New(t),
},
Setup: &Setup{
Setup: setupMock,
},
}
exitCode := cmd.Run(ctx, []string{executable, "setup",
"--oidc-issuer-url", "https://issuer.example.com",
"--oidc-client-id", "YOUR_CLIENT",
"--oidc-extra-scope", "email,profile",
}, version)
if exitCode != 0 {
t.Errorf("exitCode wants 0 but %d", exitCode)
}
})
})
}

View File

@@ -16,11 +16,13 @@ type getTokenOptions struct {
IssuerURL string
ClientID string
ClientSecret string
RedirectURL string
ExtraScopes []string
UsePKCE bool
UseAccessToken bool
TokenCacheDir string
RequestHeaders map[string]string
tokenCacheOptions tokenCacheOptions
tlsOptions tlsOptions
pkceOptions pkceOptions
authenticationOptions authenticationOptions
ForceRefresh bool
}
@@ -29,20 +31,21 @@ func (o *getTokenOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.IssuerURL, "oidc-issuer-url", "", "Issuer URL of the provider (mandatory)")
f.StringVar(&o.ClientID, "oidc-client-id", "", "Client ID of the provider (mandatory)")
f.StringVar(&o.ClientSecret, "oidc-client-secret", "", "Client secret of the provider")
f.StringVar(&o.RedirectURL, "oidc-redirect-url", "", "[authcode, authcode-keyboard] Redirect URL")
f.StringSliceVar(&o.ExtraScopes, "oidc-extra-scope", nil, "Scopes to request to the provider")
f.BoolVar(&o.UsePKCE, "oidc-use-pkce", false, "Force PKCE usage")
f.BoolVar(&o.UseAccessToken, "oidc-use-access-token", false, "Instead of using the id_token, use the access_token to authenticate to Kubernetes")
f.StringVar(&o.TokenCacheDir, "token-cache-dir", defaultTokenCacheDir, "Path to a directory for token cache")
f.StringToStringVar(&o.RequestHeaders, "oidc-request-header", nil, "HTTP headers to send with an authentication request")
f.BoolVar(&o.ForceRefresh, "force-refresh", false, "If set, refresh the ID token regardless of its expiration time")
o.tokenCacheOptions.addFlags(f)
o.tlsOptions.addFlags(f)
o.pkceOptions.addFlags(f)
o.authenticationOptions.addFlags(f)
}
func (o *getTokenOptions) expandHomedir() error {
o.TokenCacheDir = expandHomedir(o.TokenCacheDir)
func (o *getTokenOptions) expandHomedir() {
o.tokenCacheOptions.expandHomedir()
o.authenticationOptions.expandHomedir()
o.tlsOptions.expandHomedir()
return nil
}
type GetToken struct {
@@ -68,26 +71,38 @@ func (cmd *GetToken) New() *cobra.Command {
return nil
},
RunE: func(c *cobra.Command, _ []string) error {
if err := o.expandHomedir(); err != nil {
return err
}
o.expandHomedir()
grantOptionSet, err := o.authenticationOptions.grantOptionSet()
if err != nil {
return fmt.Errorf("get-token: %w", err)
}
tokenCacheConfig, err := o.tokenCacheOptions.tokenCacheConfig()
if err != nil {
return fmt.Errorf("get-token: %w", err)
}
pkceMethod, err := o.pkceOptions.pkceMethod()
if err != nil {
return fmt.Errorf("get-token: %w", err)
}
redirectURL := o.RedirectURL
if o.authenticationOptions.RedirectURLAuthCodeKeyboard != "" {
redirectURL = o.authenticationOptions.RedirectURLAuthCodeKeyboard
}
in := credentialplugin.Input{
Provider: oidc.Provider{
IssuerURL: o.IssuerURL,
ClientID: o.ClientID,
ClientSecret: o.ClientSecret,
UsePKCE: o.UsePKCE,
RedirectURL: redirectURL,
PKCEMethod: pkceMethod,
UseAccessToken: o.UseAccessToken,
ExtraScopes: o.ExtraScopes,
RequestHeaders: o.RequestHeaders,
},
TokenCacheDir: o.TokenCacheDir,
GrantOptionSet: grantOptionSet,
TLSClientConfig: o.tlsOptions.tlsClientConfig(),
ForceRefresh: o.ForceRefresh,
ForceRefresh: o.ForceRefresh,
TokenCacheConfig: tokenCacheConfig,
GrantOptionSet: grantOptionSet,
TLSClientConfig: o.tlsOptions.tlsClientConfig(),
}
if err := cmd.GetToken.Do(c.Context(), in); err != nil {
return fmt.Errorf("get-token: %w", err)

40
pkg/cmd/pkce.go Normal file
View File

@@ -0,0 +1,40 @@
package cmd
import (
"fmt"
"strings"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/spf13/pflag"
)
var allPKCEMethods = strings.Join([]string{"auto", "no", "S256"}, "|")
type pkceOptions struct {
UsePKCE bool
PKCEMethod string
}
func (o *pkceOptions) addFlags(f *pflag.FlagSet) {
f.BoolVar(&o.UsePKCE, "oidc-use-pkce", false, "Force PKCE S256 code challenge method")
if err := f.MarkDeprecated("oidc-use-pkce", "use --oidc-pkce-method instead. For the most providers, you don't need to set the flag."); err != nil {
panic(err)
}
f.StringVar(&o.PKCEMethod, "oidc-pkce-method", "auto", fmt.Sprintf("PKCE code challenge method. Automatically determined by default. One of (%s)", allPKCEMethods))
}
func (o *pkceOptions) pkceMethod() (oidc.PKCEMethod, error) {
if o.UsePKCE {
return oidc.PKCEMethodS256, nil
}
switch o.PKCEMethod {
case "auto":
return oidc.PKCEMethodAuto, nil
case "no":
return oidc.PKCEMethodNo, nil
case "S256":
return oidc.PKCEMethodS256, nil
default:
return 0, fmt.Errorf("oidc-pkce-method must be one of (%s)", allPKCEMethods)
}
}

View File

@@ -3,6 +3,8 @@ package cmd
import (
"fmt"
_ "embed"
"github.com/int128/kubelogin/pkg/usecases/setup"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@@ -13,10 +15,12 @@ type setupOptions struct {
IssuerURL string
ClientID string
ClientSecret string
RedirectURL string
ExtraScopes []string
UsePKCE bool
UseAccessToken bool
RequestHeaders map[string]string
tlsOptions tlsOptions
pkceOptions pkceOptions
authenticationOptions authenticationOptions
}
@@ -24,10 +28,12 @@ func (o *setupOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.IssuerURL, "oidc-issuer-url", "", "Issuer URL of the provider")
f.StringVar(&o.ClientID, "oidc-client-id", "", "Client ID of the provider")
f.StringVar(&o.ClientSecret, "oidc-client-secret", "", "Client secret of the provider")
f.StringVar(&o.RedirectURL, "oidc-redirect-url", "", "[authcode, authcode-keyboard] Redirect URL")
f.StringSliceVar(&o.ExtraScopes, "oidc-extra-scope", nil, "Scopes to request to the provider")
f.BoolVar(&o.UsePKCE, "oidc-use-pkce", false, "Force PKCE usage")
f.BoolVar(&o.UseAccessToken, "oidc-use-access-token", false, "Instead of using the id_token, use the access_token to authenticate to Kubernetes")
f.StringToStringVar(&o.RequestHeaders, "oidc-request-header", nil, "HTTP headers to send with an authentication request")
o.tlsOptions.addFlags(f)
o.pkceOptions.addFlags(f)
o.authenticationOptions.addFlags(f)
}
@@ -35,35 +41,56 @@ type Setup struct {
Setup setup.Interface
}
//go:embed setup.md
var setupLongDescription string
func (cmd *Setup) New() *cobra.Command {
var o setupOptions
c := &cobra.Command{
Use: "setup",
Short: "Show the setup instruction",
Long: setupLongDescription,
Args: cobra.NoArgs,
RunE: func(c *cobra.Command, _ []string) error {
var changedFlags []string
c.Flags().VisitAll(func(f *pflag.Flag) {
if !f.Changed {
return
}
if sliceValue, ok := f.Value.(pflag.SliceValue); ok {
for _, v := range sliceValue.GetSlice() {
changedFlags = append(changedFlags, fmt.Sprintf("--%s=%s", f.Name, v))
}
return
}
changedFlags = append(changedFlags, fmt.Sprintf("--%s=%s", f.Name, f.Value))
})
grantOptionSet, err := o.authenticationOptions.grantOptionSet()
if err != nil {
return fmt.Errorf("setup: %w", err)
}
in := setup.Stage2Input{
pkceMethod, err := o.pkceOptions.pkceMethod()
if err != nil {
return fmt.Errorf("setup: %w", err)
}
in := setup.Input{
IssuerURL: o.IssuerURL,
ClientID: o.ClientID,
ClientSecret: o.ClientSecret,
RedirectURL: o.RedirectURL,
ExtraScopes: o.ExtraScopes,
UsePKCE: o.UsePKCE,
UseAccessToken: o.UseAccessToken,
RequestHeaders: o.RequestHeaders,
PKCEMethod: pkceMethod,
GrantOptionSet: grantOptionSet,
TLSClientConfig: o.tlsOptions.tlsClientConfig(),
}
if c.Flags().Lookup("listen-address").Changed {
in.ListenAddressArgs = o.authenticationOptions.ListenAddress
ChangedFlags: changedFlags,
}
if in.IssuerURL == "" || in.ClientID == "" {
cmd.Setup.DoStage1()
return nil
return c.Help()
}
if err := cmd.Setup.DoStage2(c.Context(), in); err != nil {
if err := cmd.Setup.Do(c.Context(), in); err != nil {
return fmt.Errorf("setup: %w", err)
}
return nil

12
pkg/cmd/setup.md Normal file
View File

@@ -0,0 +1,12 @@
This setup shows the instruction of Kubernetes OpenID Connect authentication.
You need to set up the OpenID Connect Provider.
Run the following command to authenticate with the OpenID Connect Provider:
```
kubectl oidc-login setup \
--oidc-issuer-url=ISSUER_URL \
--oidc-client-id=YOUR_CLIENT_ID
```
See https://github.com/int128/kubelogin for the details.

View File

@@ -18,7 +18,7 @@ type tlsOptions struct {
func (o *tlsOptions) addFlags(f *pflag.FlagSet) {
f.StringArrayVar(&o.CACertFilename, "certificate-authority", nil, "Path to a cert file for the certificate authority")
f.StringArrayVar(&o.CACertData, "certificate-authority-data", nil, "Base64 encoded cert for the certificate authority")
f.BoolVar(&o.SkipTLSVerify, "insecure-skip-tls-verify", false, "If set, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure")
f.BoolVar(&o.SkipTLSVerify, "insecure-skip-tls-verify", false, "[SECURITY RISK] If set, the server's certificate will not be checked for validity")
f.BoolVar(&o.RenegotiateOnceAsClient, "tls-renegotiation-once", false, "If set, allow a remote server to request renegotiation once per connection")
f.BoolVar(&o.RenegotiateFreelyAsClient, "tls-renegotiation-freely", false, "If set, allow a remote server to repeatedly request renegotiation")
}

52
pkg/cmd/tokencache.go Normal file
View File

@@ -0,0 +1,52 @@
package cmd
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/int128/kubelogin/pkg/tokencache"
"github.com/spf13/pflag"
)
func getDefaultTokenCacheDir() string {
// https://github.com/int128/kubelogin/pull/975
if kubeCacheDir, ok := os.LookupEnv("KUBECACHEDIR"); ok {
return filepath.Join(kubeCacheDir, "oidc-login")
}
return filepath.Join("~", ".kube", "cache", "oidc-login")
}
var allTokenCacheStorage = strings.Join([]string{"disk", "keyring", "none"}, "|")
type tokenCacheOptions struct {
TokenCacheDir string
TokenCacheStorage string
}
func (o *tokenCacheOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.TokenCacheDir, "token-cache-dir", getDefaultTokenCacheDir(), "Path to a directory of the token cache")
f.StringVar(&o.TokenCacheStorage, "token-cache-storage", "disk", fmt.Sprintf("Storage for the token cache. One of (%s)", allTokenCacheStorage))
}
func (o *tokenCacheOptions) expandHomedir() {
o.TokenCacheDir = expandHomedir(o.TokenCacheDir)
}
func (o *tokenCacheOptions) tokenCacheConfig() (tokencache.Config, error) {
config := tokencache.Config{
Directory: o.TokenCacheDir,
}
switch o.TokenCacheStorage {
case "disk":
config.Storage = tokencache.StorageDisk
case "keyring":
config.Storage = tokencache.StorageKeyring
case "none":
config.Storage = tokencache.StorageNone
default:
return tokencache.Config{}, fmt.Errorf("token-cache-storage must be one of (%s)", allTokenCacheStorage)
}
return config, nil
}

View File

@@ -20,6 +20,7 @@ import (
"github.com/int128/kubelogin/pkg/tlsclientconfig/loader"
"github.com/int128/kubelogin/pkg/tokencache/repository"
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/clean"
"github.com/int128/kubelogin/pkg/usecases/credentialplugin"
"github.com/int128/kubelogin/pkg/usecases/setup"
"github.com/int128/kubelogin/pkg/usecases/standalone"
@@ -47,6 +48,7 @@ func NewCmdForHeadless(clock.Interface, stdio.Stdin, stdio.Stdout, logger.Interf
standalone.Set,
credentialplugin.Set,
setup.Set,
clean.Set,
// infrastructure
cmd.Set,

View File

@@ -22,8 +22,10 @@ import (
"github.com/int128/kubelogin/pkg/tokencache/repository"
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/authentication/clientcredentials"
"github.com/int128/kubelogin/pkg/usecases/authentication/devicecode"
"github.com/int128/kubelogin/pkg/usecases/authentication/ropc"
"github.com/int128/kubelogin/pkg/usecases/clean"
"github.com/int128/kubelogin/pkg/usecases/credentialplugin"
"github.com/int128/kubelogin/pkg/usecases/setup"
"github.com/int128/kubelogin/pkg/usecases/standalone"
@@ -75,13 +77,17 @@ func NewCmdForHeadless(clockInterface clock.Interface, stdin stdio.Stdin, stdout
Browser: browserInterface,
Logger: loggerInterface,
}
clientCredentials := &clientcredentials.ClientCredentials{
Logger: loggerInterface,
}
authenticationAuthentication := &authentication.Authentication{
ClientFactory: factory,
Logger: loggerInterface,
AuthCodeBrowser: authcodeBrowser,
AuthCodeKeyboard: keyboard,
ROPC: ropcROPC,
DeviceCode: deviceCode,
ClientFactory: factory,
Logger: loggerInterface,
AuthCodeBrowser: authcodeBrowser,
AuthCodeKeyboard: keyboard,
ROPC: ropcROPC,
DeviceCode: deviceCode,
ClientCredentials: clientCredentials,
}
loader3 := &loader2.Loader{}
writerWriter := &writer.Writer{}
@@ -120,10 +126,18 @@ func NewCmdForHeadless(clockInterface clock.Interface, stdin stdio.Stdin, stdout
cmdSetup := &cmd.Setup{
Setup: setupSetup,
}
cleanClean := &clean.Clean{
TokenCacheRepository: repositoryRepository,
Logger: loggerInterface,
}
cmdClean := &cmd.Clean{
Clean: cleanClean,
}
cmdCmd := &cmd.Cmd{
Root: root,
GetToken: cmdGetToken,
Setup: cmdSetup,
Clean: cmdClean,
Logger: loggerInterface,
}
return cmdCmd

102
pkg/oidc/client/authcode.go Normal file
View File

@@ -0,0 +1,102 @@
package client
import (
"context"
"fmt"
gooidc "github.com/coreos/go-oidc/v3/oidc"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/pkce"
"github.com/int128/oauth2cli"
"golang.org/x/oauth2"
)
type AuthCodeURLInput struct {
State string
Nonce string
PKCEParams pkce.Params
AuthRequestExtraParams map[string]string
}
type ExchangeAuthCodeInput struct {
Code string
PKCEParams pkce.Params
Nonce string
}
type GetTokenByAuthCodeInput struct {
BindAddress []string
State string
Nonce string
PKCEParams pkce.Params
RedirectURLHostname string // DEPRECATED
AuthRequestExtraParams map[string]string
LocalServerSuccessHTML string
LocalServerCertFile string
LocalServerKeyFile string
}
func (c *client) NegotiatedPKCEMethod() pkce.Method {
return c.negotiatedPKCEMethod
}
// GetTokenByAuthCode performs the authorization code flow.
func (c *client) GetTokenByAuthCode(ctx context.Context, in GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
config := oauth2cli.Config{
OAuth2Config: c.oauth2Config,
State: in.State,
AuthCodeOptions: authorizationRequestOptions(in.Nonce, in.PKCEParams, in.AuthRequestExtraParams),
TokenRequestOptions: tokenRequestOptions(in.PKCEParams),
LocalServerBindAddress: in.BindAddress,
LocalServerReadyChan: localServerReadyChan,
RedirectURLHostname: in.RedirectURLHostname,
LocalServerSuccessHTML: in.LocalServerSuccessHTML,
LocalServerCertFile: in.LocalServerCertFile,
LocalServerKeyFile: in.LocalServerKeyFile,
Logf: c.logger.V(1).Infof,
}
token, err := oauth2cli.GetToken(ctx, config)
if err != nil {
return nil, fmt.Errorf("oauth2 error: %w", err)
}
return c.verifyToken(ctx, token, in.Nonce)
}
// GetAuthCodeURL returns the URL of authentication request for the authorization code flow.
func (c *client) GetAuthCodeURL(in AuthCodeURLInput) string {
opts := authorizationRequestOptions(in.Nonce, in.PKCEParams, in.AuthRequestExtraParams)
return c.oauth2Config.AuthCodeURL(in.State, opts...)
}
// ExchangeAuthCode exchanges the authorization code and token.
func (c *client) ExchangeAuthCode(ctx context.Context, in ExchangeAuthCodeInput) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
opts := tokenRequestOptions(in.PKCEParams)
token, err := c.oauth2Config.Exchange(ctx, in.Code, opts...)
if err != nil {
return nil, fmt.Errorf("exchange error: %w", err)
}
return c.verifyToken(ctx, token, in.Nonce)
}
func authorizationRequestOptions(nonce string, pkceParams pkce.Params, extraParams map[string]string) []oauth2.AuthCodeOption {
opts := []oauth2.AuthCodeOption{
oauth2.AccessTypeOffline,
gooidc.Nonce(nonce),
}
if pkceOpt := pkceParams.AuthCodeOption(); pkceOpt != nil {
opts = append(opts, pkceOpt)
}
for key, value := range extraParams {
opts = append(opts, oauth2.SetAuthURLParam(key, value))
}
return opts
}
func tokenRequestOptions(pkceParams pkce.Params) []oauth2.AuthCodeOption {
if pkceOpt := pkceParams.TokenRequestOption(); pkceOpt != nil {
return []oauth2.AuthCodeOption{pkceOpt}
}
return nil
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/pkce"
"github.com/int128/oauth2cli"
"github.com/int128/oauth2dev"
"golang.org/x/oauth2"
)
@@ -20,49 +19,22 @@ type Interface interface {
GetAuthCodeURL(in AuthCodeURLInput) string
ExchangeAuthCode(ctx context.Context, in ExchangeAuthCodeInput) (*oidc.TokenSet, error)
GetTokenByAuthCode(ctx context.Context, in GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error)
NegotiatedPKCEMethod() pkce.Method
GetTokenByROPC(ctx context.Context, username, password string) (*oidc.TokenSet, error)
GetTokenByClientCredentials(ctx context.Context, in GetTokenByClientCredentialsInput) (*oidc.TokenSet, error)
GetDeviceAuthorization(ctx context.Context) (*oauth2dev.AuthorizationResponse, error)
ExchangeDeviceCode(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error)
Refresh(ctx context.Context, refreshToken string) (*oidc.TokenSet, error)
SupportedPKCEMethods() []string
}
type AuthCodeURLInput struct {
State string
Nonce string
PKCEParams pkce.Params
RedirectURI string
AuthRequestExtraParams map[string]string
}
type ExchangeAuthCodeInput struct {
Code string
PKCEParams pkce.Params
Nonce string
RedirectURI string
}
type GetTokenByAuthCodeInput struct {
BindAddress []string
State string
Nonce string
PKCEParams pkce.Params
RedirectURLHostname string
AuthRequestExtraParams map[string]string
LocalServerSuccessHTML string
LocalServerCertFile string
LocalServerKeyFile string
}
type client struct {
httpClient *http.Client
provider *gooidc.Provider
oauth2Config oauth2.Config
clock clock.Interface
logger logger.Interface
supportedPKCEMethods []string
deviceAuthorizationEndpoint string
useAccessToken bool
httpClient *http.Client
provider *gooidc.Provider
oauth2Config oauth2.Config
clock clock.Interface
logger logger.Interface
negotiatedPKCEMethod pkce.Method
useAccessToken bool
}
func (c *client) wrapContext(ctx context.Context) context.Context {
@@ -72,110 +44,6 @@ func (c *client) wrapContext(ctx context.Context) context.Context {
return ctx
}
// GetTokenByAuthCode performs the authorization code flow.
func (c *client) GetTokenByAuthCode(ctx context.Context, in GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
config := oauth2cli.Config{
OAuth2Config: c.oauth2Config,
State: in.State,
AuthCodeOptions: authorizationRequestOptions(in.Nonce, in.PKCEParams, in.AuthRequestExtraParams),
TokenRequestOptions: tokenRequestOptions(in.PKCEParams),
LocalServerBindAddress: in.BindAddress,
LocalServerReadyChan: localServerReadyChan,
RedirectURLHostname: in.RedirectURLHostname,
LocalServerSuccessHTML: in.LocalServerSuccessHTML,
LocalServerCertFile: in.LocalServerCertFile,
LocalServerKeyFile: in.LocalServerKeyFile,
Logf: c.logger.V(1).Infof,
}
token, err := oauth2cli.GetToken(ctx, config)
if err != nil {
return nil, fmt.Errorf("oauth2 error: %w", err)
}
return c.verifyToken(ctx, token, in.Nonce)
}
// GetAuthCodeURL returns the URL of authentication request for the authorization code flow.
func (c *client) GetAuthCodeURL(in AuthCodeURLInput) string {
cfg := c.oauth2Config
cfg.RedirectURL = in.RedirectURI
opts := authorizationRequestOptions(in.Nonce, in.PKCEParams, in.AuthRequestExtraParams)
return cfg.AuthCodeURL(in.State, opts...)
}
// ExchangeAuthCode exchanges the authorization code and token.
func (c *client) ExchangeAuthCode(ctx context.Context, in ExchangeAuthCodeInput) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
cfg := c.oauth2Config
cfg.RedirectURL = in.RedirectURI
opts := tokenRequestOptions(in.PKCEParams)
token, err := cfg.Exchange(ctx, in.Code, opts...)
if err != nil {
return nil, fmt.Errorf("exchange error: %w", err)
}
return c.verifyToken(ctx, token, in.Nonce)
}
func authorizationRequestOptions(n string, p pkce.Params, e map[string]string) []oauth2.AuthCodeOption {
o := []oauth2.AuthCodeOption{
oauth2.AccessTypeOffline,
gooidc.Nonce(n),
}
if !p.IsZero() {
o = append(o,
oauth2.SetAuthURLParam("code_challenge", p.CodeChallenge),
oauth2.SetAuthURLParam("code_challenge_method", p.CodeChallengeMethod),
)
}
for key, value := range e {
o = append(o, oauth2.SetAuthURLParam(key, value))
}
return o
}
func tokenRequestOptions(p pkce.Params) (o []oauth2.AuthCodeOption) {
if !p.IsZero() {
o = append(o, oauth2.SetAuthURLParam("code_verifier", p.CodeVerifier))
}
return
}
// SupportedPKCEMethods returns the PKCE methods supported by the provider.
// This may return nil if PKCE is not supported.
func (c *client) SupportedPKCEMethods() []string {
return c.supportedPKCEMethods
}
// GetTokenByROPC performs the resource owner password credentials flow.
func (c *client) GetTokenByROPC(ctx context.Context, username, password string) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
token, err := c.oauth2Config.PasswordCredentialsToken(ctx, username, password)
if err != nil {
return nil, fmt.Errorf("resource owner password credentials flow error: %w", err)
}
return c.verifyToken(ctx, token, "")
}
// GetDeviceAuthorization initializes the device authorization code challenge
func (c *client) GetDeviceAuthorization(ctx context.Context) (*oauth2dev.AuthorizationResponse, error) {
ctx = c.wrapContext(ctx)
config := c.oauth2Config
config.Endpoint = oauth2.Endpoint{
AuthURL: c.deviceAuthorizationEndpoint,
}
return oauth2dev.RetrieveCode(ctx, config)
}
// ExchangeDeviceCode exchanges the device to an oidc.TokenSet
func (c *client) ExchangeDeviceCode(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
tokenResponse, err := oauth2dev.PollToken(ctx, c.oauth2Config, *authResponse)
if err != nil {
return nil, fmt.Errorf("device-code: exchange failed: %w", err)
}
return c.verifyToken(ctx, tokenResponse, "")
}
// Refresh sends a refresh token request and returns a token set.
func (c *client) Refresh(ctx context.Context, refreshToken string) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)

View File

@@ -0,0 +1,41 @@
package client
import (
"context"
"fmt"
"github.com/int128/kubelogin/pkg/oidc"
"golang.org/x/oauth2"
"golang.org/x/oauth2/clientcredentials"
)
type GetTokenByClientCredentialsInput struct {
EndpointParams map[string][]string
}
// GetTokenByClientCredentials performs the client credentials flow.
func (c *client) GetTokenByClientCredentials(ctx context.Context, in GetTokenByClientCredentialsInput) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
c.logger.V(1).Infof("%s, %s, %v", c.oauth2Config.ClientID, c.oauth2Config.Endpoint.AuthURL, c.oauth2Config.Scopes)
config := clientcredentials.Config{
ClientID: c.oauth2Config.ClientID,
ClientSecret: c.oauth2Config.ClientSecret,
TokenURL: c.oauth2Config.Endpoint.TokenURL,
Scopes: c.oauth2Config.Scopes,
EndpointParams: in.EndpointParams,
AuthStyle: oauth2.AuthStyleInHeader,
}
source := config.TokenSource(ctx)
token, err := source.Token()
if err != nil {
return nil, fmt.Errorf("could not acquire token: %w", err)
}
if c.useAccessToken {
return &oidc.TokenSet{
IDToken: token.AccessToken,
RefreshToken: token.RefreshToken,
}, nil
}
return c.verifyToken(ctx, token, "")
}

View File

@@ -0,0 +1,30 @@
package client
import (
"context"
"fmt"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/oauth2dev"
"golang.org/x/oauth2"
)
// GetDeviceAuthorization initializes the device authorization code challenge
func (c *client) GetDeviceAuthorization(ctx context.Context) (*oauth2dev.AuthorizationResponse, error) {
ctx = c.wrapContext(ctx)
config := c.oauth2Config
config.Endpoint = oauth2.Endpoint{
AuthURL: c.provider.Endpoint().DeviceAuthURL,
}
return oauth2dev.RetrieveCode(ctx, config)
}
// ExchangeDeviceCode exchanges the device authorization code for an oidc.TokenSet
func (c *client) ExchangeDeviceCode(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
tokenResponse, err := oauth2dev.PollToken(ctx, c.oauth2Config, *authResponse)
if err != nil {
return nil, fmt.Errorf("device-code: exchange failed: %w", err)
}
return c.verifyToken(ctx, tokenResponse, "")
}

View File

@@ -5,13 +5,14 @@ import (
"context"
"fmt"
"net/http"
"slices"
gooidc "github.com/coreos/go-oidc/v3/oidc"
"github.com/google/wire"
"github.com/int128/kubelogin/pkg/infrastructure/clock"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client/logging"
"github.com/int128/kubelogin/pkg/oidc/client/transport"
"github.com/int128/kubelogin/pkg/pkce"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
"github.com/int128/kubelogin/pkg/tlsclientconfig/loader"
@@ -24,7 +25,7 @@ var Set = wire.NewSet(
)
type FactoryInterface interface {
New(ctx context.Context, p oidc.Provider, tlsClientConfig tlsclientconfig.Config) (Interface, error)
New(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config) (Interface, error)
}
type Factory struct {
@@ -34,25 +35,26 @@ type Factory struct {
}
// New returns an instance of infrastructure.Interface with the given configuration.
func (f *Factory) New(ctx context.Context, p oidc.Provider, tlsClientConfig tlsclientconfig.Config) (Interface, error) {
func (f *Factory) New(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config) (Interface, error) {
rawTLSClientConfig, err := f.Loader.Load(tlsClientConfig)
if err != nil {
return nil, fmt.Errorf("could not load the TLS client config: %w", err)
}
baseTransport := &http.Transport{
TLSClientConfig: rawTLSClientConfig,
Proxy: http.ProxyFromEnvironment,
}
loggingTransport := &logging.Transport{
Base: baseTransport,
Logger: f.Logger,
}
httpClient := &http.Client{
Transport: loggingTransport,
Transport: &transport.WithHeader{
Base: &transport.WithLogging{
Base: &http.Transport{
TLSClientConfig: rawTLSClientConfig,
Proxy: http.ProxyFromEnvironment,
},
Logger: f.Logger,
},
RequestHeaders: prov.RequestHeaders,
},
}
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
provider, err := gooidc.NewProvider(ctx, p.IssuerURL)
provider, err := gooidc.NewProvider(ctx, prov.IssuerURL)
if err != nil {
return nil, fmt.Errorf("oidc discovery error: %w", err)
}
@@ -60,46 +62,43 @@ func (f *Factory) New(ctx context.Context, p oidc.Provider, tlsClientConfig tlsc
if err != nil {
return nil, fmt.Errorf("could not determine supported PKCE methods: %w", err)
}
if len(supportedPKCEMethods) == 0 && p.UsePKCE {
supportedPKCEMethods = []string{pkce.MethodS256}
}
deviceAuthorizationEndpoint, err := extractDeviceAuthorizationEndpoint(provider)
if err != nil {
return nil, fmt.Errorf("could not determine device authorization endpoint: %w", err)
}
return &client{
httpClient: httpClient,
provider: provider,
oauth2Config: oauth2.Config{
Endpoint: provider.Endpoint(),
ClientID: p.ClientID,
ClientSecret: p.ClientSecret,
Scopes: append(p.ExtraScopes, gooidc.ScopeOpenID),
ClientID: prov.ClientID,
ClientSecret: prov.ClientSecret,
RedirectURL: prov.RedirectURL,
Scopes: append(prov.ExtraScopes, gooidc.ScopeOpenID),
},
clock: f.Clock,
logger: f.Logger,
supportedPKCEMethods: supportedPKCEMethods,
deviceAuthorizationEndpoint: deviceAuthorizationEndpoint,
useAccessToken: p.UseAccessToken,
clock: f.Clock,
logger: f.Logger,
negotiatedPKCEMethod: determinePKCEMethod(supportedPKCEMethods, prov.PKCEMethod),
useAccessToken: prov.UseAccessToken,
}, nil
}
func extractSupportedPKCEMethods(provider *gooidc.Provider) ([]string, error) {
var d struct {
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
func determinePKCEMethod(supportedMethods []string, preferredMethod oidc.PKCEMethod) pkce.Method {
switch preferredMethod {
case oidc.PKCEMethodNo:
return pkce.NoMethod
case oidc.PKCEMethodS256:
return pkce.MethodS256
default:
if slices.Contains(supportedMethods, "S256") {
return pkce.MethodS256
}
return pkce.NoMethod
}
if err := provider.Claims(&d); err != nil {
return nil, fmt.Errorf("invalid discovery document: %w", err)
}
return d.CodeChallengeMethodsSupported, nil
}
func extractDeviceAuthorizationEndpoint(provider *gooidc.Provider) (string, error) {
var d struct {
DeviceAuthorizationEndpoint string `json:"device_authorization_endpoint"`
func extractSupportedPKCEMethods(provider *gooidc.Provider) ([]string, error) {
var claims struct {
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
}
if err := provider.Claims(&d); err != nil {
return "", fmt.Errorf("invalid discovery document: %w", err)
if err := provider.Claims(&claims); err != nil {
return nil, fmt.Errorf("invalid discovery document: %w", err)
}
return d.DeviceAuthorizationEndpoint, nil
return claims.CodeChallengeMethodsSupported, nil
}

18
pkg/oidc/client/ropc.go Normal file
View File

@@ -0,0 +1,18 @@
package client
import (
"context"
"fmt"
"github.com/int128/kubelogin/pkg/oidc"
)
// GetTokenByROPC performs the resource owner password credentials flow.
func (c *client) GetTokenByROPC(ctx context.Context, username, password string) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
token, err := c.oauth2Config.PasswordCredentialsToken(ctx, username, password)
if err != nil {
return nil, fmt.Errorf("resource owner password credentials flow error: %w", err)
}
return c.verifyToken(ctx, token, "")
}

View File

@@ -0,0 +1,21 @@
package transport
import "net/http"
// WithHeader is a RoundTripper that adds custom headers to each request.
//
// Token retrievel fails when an auth code has been retrieved using Azure AD
// Single Page Application due to the missing "Origin" header for CORS
// validation.
// https://github.com/int128/kubelogin/issues/1048
type WithHeader struct {
Base http.RoundTripper
RequestHeaders map[string]string
}
func (t *WithHeader) RoundTrip(req *http.Request) (*http.Response, error) {
for key, value := range t.RequestHeaders {
req.Header.Set(key, value)
}
return t.Base.RoundTrip(req)
}

View File

@@ -1,4 +1,4 @@
package logging
package transport
import (
"net/http"
@@ -12,12 +12,12 @@ const (
levelDumpBody = 3
)
type Transport struct {
type WithLogging struct {
Base http.RoundTripper
Logger logger.Interface
}
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
func (t *WithLogging) RoundTrip(req *http.Request) (*http.Response, error) {
if !t.Logger.IsEnabled(levelDumpHeaders) {
return t.Base.RoundTrip(req)
}

View File

@@ -1,4 +1,4 @@
package logging
package transport
import (
"bufio"
@@ -20,7 +20,7 @@ func (t *mockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return t.resp, nil
}
func TestLoggingTransport_RoundTrip(t *testing.T) {
func TestWithLogging_RoundTrip(t *testing.T) {
req := httptest.NewRequest("GET", "http://example.com/hello", nil)
resp, err := http.ReadResponse(bufio.NewReader(strings.NewReader(`HTTP/1.1 200 OK
Host: example.com
@@ -29,9 +29,13 @@ dummy`)), req)
if err != nil {
t.Errorf("could not create a response: %s", err)
}
defer resp.Body.Close()
defer func() {
if err := resp.Body.Close(); err != nil {
t.Errorf("could not close response body: %s", err)
}
}()
transport := &Transport{
transport := &WithLogging{
Base: &mockTransport{resp: resp},
Logger: logger.New(t),
}

View File

@@ -15,10 +15,21 @@ type Provider struct {
ClientID string
ClientSecret string // optional
ExtraScopes []string // optional
UsePKCE bool // optional
UseAccessToken bool // optional
RedirectURL string // optional
PKCEMethod PKCEMethod
UseAccessToken bool
RequestHeaders map[string]string
}
// PKCEMethod represents a preferred method of PKCE.
type PKCEMethod int
const (
PKCEMethodAuto PKCEMethod = iota
PKCEMethodNo
PKCEMethodS256
)
// TokenSet represents a set of ID token and refresh token.
type TokenSet struct {
IDToken string

View File

@@ -2,72 +2,45 @@
// See also https://tools.ietf.org/html/rfc7636.
package pkce
import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/binary"
"fmt"
)
import "golang.org/x/oauth2"
var Plain Params
type Method int
const (
// code challenge methods defined as https://tools.ietf.org/html/rfc7636#section-4.3
MethodS256 = "S256"
// Code challenge methods defined as https://tools.ietf.org/html/rfc7636#section-4.3
NoMethod Method = iota
MethodS256
)
// Params represents a set of the PKCE parameters.
type Params struct {
CodeChallenge string
CodeChallengeMethod string
CodeVerifier string
Method Method
Verifier string
}
func (p Params) IsZero() bool {
return p == Params{}
func (params Params) AuthCodeOption() oauth2.AuthCodeOption {
if params.Method == MethodS256 {
return oauth2.S256ChallengeOption(params.Verifier)
}
return nil
}
func (params Params) TokenRequestOption() oauth2.AuthCodeOption {
if params.Method == MethodS256 {
return oauth2.VerifierOption(params.Verifier)
}
return nil
}
// New returns a parameters supported by the provider.
// You need to pass the code challenge methods defined in RFC7636.
// It returns Plain if no method is available.
func New(methods []string) (Params, error) {
for _, method := range methods {
if method == MethodS256 {
return NewS256()
}
// It returns a zero value if no method is available.
func New(method Method) (Params, error) {
if method == MethodS256 {
return Params{
Method: MethodS256,
Verifier: oauth2.GenerateVerifier(),
}, nil
}
return Plain, nil
}
// NewS256 generates a parameters for S256.
func NewS256() (Params, error) {
b, err := random32()
if err != nil {
return Plain, fmt.Errorf("could not generate a random: %w", err)
}
return computeS256(b), nil
}
func random32() ([]byte, error) {
b := make([]byte, 32)
if err := binary.Read(rand.Reader, binary.LittleEndian, b); err != nil {
return nil, fmt.Errorf("read error: %w", err)
}
return b, nil
}
func computeS256(b []byte) Params {
v := base64URLEncode(b)
s := sha256.New()
_, _ = s.Write([]byte(v))
return Params{
CodeChallenge: base64URLEncode(s.Sum(nil)),
CodeChallengeMethod: MethodS256,
CodeVerifier: v,
}
}
func base64URLEncode(b []byte) string {
return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(b)
return Params{}, nil
}

View File

@@ -1,61 +0,0 @@
package pkce
import (
"testing"
)
func TestNew(t *testing.T) {
t.Run("S256", func(t *testing.T) {
p, err := New([]string{"plain", "S256"})
if err != nil {
t.Fatalf("New error: %s", err)
}
if p.CodeChallengeMethod != "S256" {
t.Errorf("CodeChallengeMethod wants S256 but was %s", p.CodeChallengeMethod)
}
if p.CodeChallenge == "" {
t.Errorf("CodeChallenge wants non-empty but was empty")
}
if p.CodeVerifier == "" {
t.Errorf("CodeVerifier wants non-empty but was empty")
}
})
t.Run("plain", func(t *testing.T) {
p, err := New([]string{"plain"})
if err != nil {
t.Fatalf("New error: %s", err)
}
if !p.IsZero() {
t.Errorf("IsZero wants true but was false")
}
})
t.Run("nil", func(t *testing.T) {
p, err := New(nil)
if err != nil {
t.Fatalf("New error: %s", err)
}
if !p.IsZero() {
t.Errorf("IsZero wants true but was false")
}
})
}
func Test_computeS256(t *testing.T) {
// Testdata described at:
// https://tools.ietf.org/html/rfc7636#appendix-B
b := []byte{
116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173,
187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83,
132, 141, 121,
}
p := computeS256(b)
if want := "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"; want != p.CodeVerifier {
t.Errorf("CodeVerifier wants %s but was %s", want, p.CodeVerifier)
}
if want := "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"; want != p.CodeChallenge {
t.Errorf("CodeChallenge wants %s but was %s", want, p.CodeChallenge)
}
if p.CodeChallengeMethod != "S256" {
t.Errorf("CodeChallengeMethod wants S256 but was %s", p.CodeChallengeMethod)
}
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/google/wire"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/tokencache"
"github.com/zalando/go-keyring"
)
// Set provides an implementation and interface for Kubeconfig.
@@ -23,9 +24,10 @@ var Set = wire.NewSet(
)
type Interface interface {
FindByKey(dir string, key tokencache.Key) (*oidc.TokenSet, error)
Save(dir string, key tokencache.Key, tokenSet oidc.TokenSet) error
Lock(dir string, key tokencache.Key) (io.Closer, error)
FindByKey(config tokencache.Config, key tokencache.Key) (*oidc.TokenSet, error)
Save(config tokencache.Config, key tokencache.Key, tokenSet oidc.TokenSet) error
Lock(config tokencache.Config, key tokencache.Key) (io.Closer, error)
DeleteAll(config tokencache.Config) error
}
type entity struct {
@@ -37,21 +39,62 @@ type entity struct {
// Filename of a token cache is sha256 digest of the issuer, zero-character and client ID.
type Repository struct{}
func (r *Repository) FindByKey(dir string, key tokencache.Key) (*oidc.TokenSet, error) {
filename, err := computeFilename(key)
// keyringService is used to namespace the keyring access.
// Some implementations may also display this string when prompting the user
// for allowing access.
const keyringService = "kubelogin"
// keyringItemPrefix is used as the prefix in the keyring items.
const keyringItemPrefix = "kubelogin/tokencache/"
func (r *Repository) FindByKey(config tokencache.Config, key tokencache.Key) (*oidc.TokenSet, error) {
checksum, err := computeChecksum(key)
if err != nil {
return nil, fmt.Errorf("could not compute the key: %w", err)
}
p := filepath.Join(dir, filename)
f, err := os.Open(p)
switch config.Storage {
case tokencache.StorageDisk:
return readFromFile(config, checksum)
case tokencache.StorageKeyring:
return readFromKeyring(checksum)
case tokencache.StorageNone:
return nil, nil
default:
return nil, fmt.Errorf("unknown storage mode: %v", config.Storage)
}
}
func readFromFile(config tokencache.Config, checksum string) (*oidc.TokenSet, error) {
p := filepath.Join(config.Directory, checksum)
b, err := os.ReadFile(p)
if err != nil {
return nil, fmt.Errorf("could not open file %s: %w", p, err)
}
defer f.Close()
d := json.NewDecoder(f)
t, err := decodeKey(b)
if err != nil {
return nil, fmt.Errorf("file %s: %w", p, err)
}
return t, nil
}
func readFromKeyring(checksum string) (*oidc.TokenSet, error) {
p := keyringItemPrefix + checksum
s, err := keyring.Get(keyringService, p)
if err != nil {
return nil, fmt.Errorf("could not get keyring secret %s: %w", p, err)
}
t, err := decodeKey([]byte(s))
if err != nil {
return nil, fmt.Errorf("keyring %s: %w", p, err)
}
return t, nil
}
func decodeKey(b []byte) (*oidc.TokenSet, error) {
var e entity
if err := d.Decode(&e); err != nil {
return nil, fmt.Errorf("invalid json file %s: %w", p, err)
err := json.Unmarshal(b, &e)
if err != nil {
return nil, fmt.Errorf("invalid token cache json: %w", err)
}
return &oidc.TokenSet{
IDToken: e.IDToken,
@@ -59,41 +102,71 @@ func (r *Repository) FindByKey(dir string, key tokencache.Key) (*oidc.TokenSet,
}, nil
}
func (r *Repository) Save(dir string, key tokencache.Key, tokenSet oidc.TokenSet) error {
if err := os.MkdirAll(dir, 0700); err != nil {
return fmt.Errorf("could not create directory %s: %w", dir, err)
}
filename, err := computeFilename(key)
func (r *Repository) Save(config tokencache.Config, key tokencache.Key, tokenSet oidc.TokenSet) error {
checksum, err := computeChecksum(key)
if err != nil {
return fmt.Errorf("could not compute the key: %w", err)
}
p := filepath.Join(dir, filename)
f, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
switch config.Storage {
case tokencache.StorageDisk:
return writeToFile(config, checksum, tokenSet)
case tokencache.StorageKeyring:
return writeToKeyring(checksum, tokenSet)
case tokencache.StorageNone:
return nil
default:
return fmt.Errorf("unknown storage mode: %v", config.Storage)
}
}
func writeToFile(config tokencache.Config, checksum string, tokenSet oidc.TokenSet) error {
p := filepath.Join(config.Directory, checksum)
b, err := encodeKey(tokenSet)
if err != nil {
return fmt.Errorf("file %s: %w", p, err)
}
if err := os.MkdirAll(config.Directory, 0700); err != nil {
return fmt.Errorf("could not create directory %s: %w", config.Directory, err)
}
if err := os.WriteFile(p, b, 0600); err != nil {
return fmt.Errorf("could not create file %s: %w", p, err)
}
defer f.Close()
e := entity{
IDToken: tokenSet.IDToken,
RefreshToken: tokenSet.RefreshToken,
}
if err := json.NewEncoder(f).Encode(&e); err != nil {
return fmt.Errorf("json encode error: %w", err)
}
return nil
}
func (r *Repository) Lock(tokenCacheDir string, key tokencache.Key) (io.Closer, error) {
if err := os.MkdirAll(tokenCacheDir, 0700); err != nil {
return nil, fmt.Errorf("could not create directory %s: %w", tokenCacheDir, err)
func writeToKeyring(checksum string, tokenSet oidc.TokenSet) error {
p := keyringItemPrefix + checksum
b, err := encodeKey(tokenSet)
if err != nil {
return fmt.Errorf("keyring %s: %w", p, err)
}
keyDigest, err := computeFilename(key)
if err := keyring.Set(keyringService, p, string(b)); err != nil {
return fmt.Errorf("keyring write %s: %w", p, err)
}
return nil
}
// Implement io.Closer for noneStorage type
type noneStorageCloser struct{}
func (c noneStorageCloser) Close() error { return nil }
func (r *Repository) Lock(config tokencache.Config, key tokencache.Key) (io.Closer, error) {
if config.Storage == tokencache.StorageNone {
return noneStorageCloser{}, nil
}
checksum, err := computeChecksum(key)
if err != nil {
return nil, fmt.Errorf("could not compute the key: %w", err)
}
// NOTE: Both keyring and disk storage types use files for locking
// No sensitive data is stored in the lock file
if err := os.MkdirAll(config.Directory, 0700); err != nil {
return nil, fmt.Errorf("could not create directory %s: %w", config.Directory, err)
}
// Do not lock the token cache file.
// https://github.com/int128/kubelogin/issues/1144
lockFilepath := filepath.Join(tokenCacheDir, keyDigest+".lock")
lockFilepath := filepath.Join(config.Directory, checksum+".lock")
lockFile := flock.New(lockFilepath)
if err := lockFile.Lock(); err != nil {
return nil, fmt.Errorf("could not lock the cache file %s: %w", lockFilepath, err)
@@ -101,7 +174,34 @@ func (r *Repository) Lock(tokenCacheDir string, key tokencache.Key) (io.Closer,
return lockFile, nil
}
func computeFilename(key tokencache.Key) (string, error) {
func (r *Repository) DeleteAll(config tokencache.Config) error {
switch config.Storage {
case tokencache.StorageDisk:
if err := os.RemoveAll(config.Directory); err != nil {
return fmt.Errorf("remove the directory %s: %w", config.Directory, err)
}
return nil
case tokencache.StorageKeyring:
if err := keyring.DeleteAll(keyringService); err != nil {
return fmt.Errorf("keyring delete: %w", err)
}
return nil
case tokencache.StorageNone:
return nil
default:
return fmt.Errorf("unknown storage mode: %v", config.Storage)
}
}
func encodeKey(tokenSet oidc.TokenSet) ([]byte, error) {
e := entity{
IDToken: tokenSet.IDToken,
RefreshToken: tokenSet.RefreshToken,
}
return json.Marshal(&e)
}
func computeChecksum(key tokencache.Key) (string, error) {
s := sha256.New()
e := gob.NewEncoder(s)
if err := e.Encode(&key); err != nil {

View File

@@ -16,6 +16,10 @@ func TestRepository_FindByKey(t *testing.T) {
t.Run("Success", func(t *testing.T) {
dir := t.TempDir()
config := tokencache.Config{
Directory: dir,
Storage: tokencache.StorageDisk,
}
key := tokencache.Key{
Provider: oidc.Provider{
IssuerURL: "YOUR_ISSUER",
@@ -27,8 +31,9 @@ func TestRepository_FindByKey(t *testing.T) {
CACertFilename: []string{"/path/to/cert"},
},
}
json := `{"id_token":"YOUR_ID_TOKEN","refresh_token":"YOUR_REFRESH_TOKEN"}`
filename, err := computeFilename(key)
filename, err := computeChecksum(key)
if err != nil {
t.Errorf("could not compute the key: %s", err)
}
@@ -37,7 +42,7 @@ func TestRepository_FindByKey(t *testing.T) {
t.Fatalf("could not write to the temp file: %s", err)
}
got, err := r.FindByKey(dir, key)
got, err := r.FindByKey(config, key)
if err != nil {
t.Errorf("err wants nil but %+v", err)
}
@@ -53,6 +58,10 @@ func TestRepository_Save(t *testing.T) {
t.Run("Success", func(t *testing.T) {
dir := t.TempDir()
config := tokencache.Config{
Directory: dir,
Storage: tokencache.StorageDisk,
}
key := tokencache.Key{
Provider: oidc.Provider{
IssuerURL: "YOUR_ISSUER",
@@ -65,11 +74,11 @@ func TestRepository_Save(t *testing.T) {
},
}
tokenSet := oidc.TokenSet{IDToken: "YOUR_ID_TOKEN", RefreshToken: "YOUR_REFRESH_TOKEN"}
if err := r.Save(dir, key, tokenSet); err != nil {
if err := r.Save(config, key, tokenSet); err != nil {
t.Errorf("err wants nil but %+v", err)
}
filename, err := computeFilename(key)
filename, err := computeChecksum(key)
if err != nil {
t.Errorf("could not compute the key: %s", err)
}
@@ -78,8 +87,7 @@ func TestRepository_Save(t *testing.T) {
if err != nil {
t.Fatalf("could not read the token cache file: %s", err)
}
want := `{"id_token":"YOUR_ID_TOKEN","refresh_token":"YOUR_REFRESH_TOKEN"}
`
want := `{"id_token":"YOUR_ID_TOKEN","refresh_token":"YOUR_REFRESH_TOKEN"}`
got := string(b)
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)

View File

@@ -11,3 +11,24 @@ type Key struct {
TLSClientConfig tlsclientconfig.Config
Username string
}
// Config represents a configuration for the token cache.
type Config struct {
// Directory is a path to the directory to store a token cache.
// Note that a lock file is created into this directory even if the keyring is used.
Directory string
Storage Storage
}
// Storage is an enum of different storage strategies.
type Storage byte
const (
// StorageDisk will only store cached keys on disk.
StorageDisk Storage = iota
// StorageDisk will only store cached keys in the OS keyring.
StorageKeyring
// StorageNone will not store cached keys.
StorageNone
)

View File

@@ -19,7 +19,7 @@ type BrowserOption struct {
BindAddress []string
AuthenticationTimeout time.Duration
OpenURLAfterAuthentication string
RedirectURLHostname string
RedirectURLHostname string // DEPRECATED
AuthRequestExtraParams map[string]string
LocalServerCertFile string
LocalServerKeyFile string
@@ -41,9 +41,9 @@ func (u *Browser) Do(ctx context.Context, o *BrowserOption, oidcClient client.In
if err != nil {
return nil, fmt.Errorf("could not generate a nonce: %w", err)
}
p, err := pkce.New(oidcClient.SupportedPKCEMethods())
pkceParams, err := pkce.New(oidcClient.NegotiatedPKCEMethod())
if err != nil {
return nil, fmt.Errorf("could not generate PKCE parameters: %w", err)
return nil, fmt.Errorf("could not generate the PKCE parameters: %w", err)
}
successHTML := BrowserSuccessHTML
if o.OpenURLAfterAuthentication != "" {
@@ -53,7 +53,7 @@ func (u *Browser) Do(ctx context.Context, o *BrowserOption, oidcClient client.In
BindAddress: o.BindAddress,
State: state,
Nonce: nonce,
PKCEParams: p,
PKCEParams: pkceParams,
RedirectURLHostname: o.RedirectURLHostname,
AuthRequestExtraParams: o.AuthRequestExtraParams,
LocalServerSuccessHTML: successHTML,

View File

@@ -10,6 +10,7 @@ import (
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/oidc/client_mock"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client"
"github.com/int128/kubelogin/pkg/pkce"
"github.com/int128/kubelogin/pkg/testing/logger"
"github.com/stretchr/testify/mock"
)
@@ -27,13 +28,10 @@ func TestBrowser_Do(t *testing.T) {
LocalServerCertFile: "/path/to/local-server-cert",
LocalServerKeyFile: "/path/to/local-server-key",
OpenURLAfterAuthentication: "https://example.com/success.html",
RedirectURLHostname: "localhost",
AuthRequestExtraParams: map[string]string{"ttl": "86400", "reauth": "true"},
}
mockClient := client_mock.NewMockInterface(t)
mockClient.EXPECT().
SupportedPKCEMethods().
Return(nil)
mockClient.EXPECT().NegotiatedPKCEMethod().Return(pkce.NoMethod)
mockClient.EXPECT().
GetTokenByAuthCode(mock.Anything, mock.Anything, mock.Anything).
Run(func(_ context.Context, in client.GetTokenByAuthCodeInput, readyChan chan<- string) {
@@ -43,9 +41,6 @@ func TestBrowser_Do(t *testing.T) {
if diff := cmp.Diff(BrowserRedirectHTML("https://example.com/success.html"), in.LocalServerSuccessHTML); diff != "" {
t.Errorf("LocalServerSuccessHTML mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(o.RedirectURLHostname, in.RedirectURLHostname); diff != "" {
t.Errorf("RedirectURLHostname mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(o.AuthRequestExtraParams, in.AuthRequestExtraParams); diff != "" {
t.Errorf("AuthRequestExtraParams mismatch (-want +got):\n%s", diff)
}
@@ -85,9 +80,7 @@ func TestBrowser_Do(t *testing.T) {
AuthenticationTimeout: 10 * time.Second,
}
mockClient := client_mock.NewMockInterface(t)
mockClient.EXPECT().
SupportedPKCEMethods().
Return(nil)
mockClient.EXPECT().NegotiatedPKCEMethod().Return(pkce.NoMethod)
mockClient.EXPECT().
GetTokenByAuthCode(mock.Anything, mock.Anything, mock.Anything).
Run(func(_ context.Context, _ client.GetTokenByAuthCodeInput, readyChan chan<- string) {
@@ -127,9 +120,7 @@ func TestBrowser_Do(t *testing.T) {
AuthenticationTimeout: 10 * time.Second,
}
mockClient := client_mock.NewMockInterface(t)
mockClient.EXPECT().
SupportedPKCEMethods().
Return(nil)
mockClient.EXPECT().NegotiatedPKCEMethod().Return(pkce.NoMethod)
mockClient.EXPECT().
GetTokenByAuthCode(mock.Anything, mock.Anything, mock.Anything).
Run(func(_ context.Context, _ client.GetTokenByAuthCodeInput, readyChan chan<- string) {

View File

@@ -15,7 +15,6 @@ const keyboardPrompt = "Enter code: "
type KeyboardOption struct {
AuthRequestExtraParams map[string]string
RedirectURL string
}
// Keyboard provides the authorization code flow with keyboard interactive.
@@ -34,16 +33,14 @@ func (u *Keyboard) Do(ctx context.Context, o *KeyboardOption, oidcClient client.
if err != nil {
return nil, fmt.Errorf("could not generate a nonce: %w", err)
}
p, err := pkce.New(oidcClient.SupportedPKCEMethods())
pkceParams, err := pkce.New(oidcClient.NegotiatedPKCEMethod())
if err != nil {
return nil, fmt.Errorf("could not generate PKCE parameters: %w", err)
return nil, fmt.Errorf("could not generate the PKCE parameters: %w", err)
}
authCodeURL := oidcClient.GetAuthCodeURL(client.AuthCodeURLInput{
State: state,
Nonce: nonce,
PKCEParams: p,
RedirectURI: o.RedirectURL,
PKCEParams: pkceParams,
AuthRequestExtraParams: o.AuthRequestExtraParams,
})
u.Logger.Printf("Please visit the following URL in your browser: %s", authCodeURL)
@@ -54,10 +51,9 @@ func (u *Keyboard) Do(ctx context.Context, o *KeyboardOption, oidcClient client.
u.Logger.V(1).Infof("exchanging the code and token")
tokenSet, err := oidcClient.ExchangeAuthCode(ctx, client.ExchangeAuthCodeInput{
Code: code,
PKCEParams: p,
Nonce: nonce,
RedirectURI: o.RedirectURL,
Code: code,
PKCEParams: pkceParams,
Nonce: nonce,
})
if err != nil {
return nil, fmt.Errorf("could not exchange the authorization code: %w", err)

View File

@@ -10,6 +10,7 @@ import (
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/oidc/client_mock"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client"
"github.com/int128/kubelogin/pkg/pkce"
"github.com/int128/kubelogin/pkg/testing/logger"
"github.com/stretchr/testify/mock"
)
@@ -24,9 +25,7 @@ func TestKeyboard_Do(t *testing.T) {
AuthRequestExtraParams: map[string]string{"ttl": "86400", "reauth": "true"},
}
mockClient := client_mock.NewMockInterface(t)
mockClient.EXPECT().
SupportedPKCEMethods().
Return(nil)
mockClient.EXPECT().NegotiatedPKCEMethod().Return(pkce.NoMethod)
mockClient.EXPECT().
GetAuthCodeURL(mock.Anything).
Run(func(in client.AuthCodeURLInput) {

View File

@@ -10,6 +10,7 @@ import (
"github.com/int128/kubelogin/pkg/oidc/client"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/authentication/clientcredentials"
"github.com/int128/kubelogin/pkg/usecases/authentication/devicecode"
"github.com/int128/kubelogin/pkg/usecases/authentication/ropc"
)
@@ -22,6 +23,7 @@ var Set = wire.NewSet(
wire.Struct(new(authcode.Keyboard), "*"),
wire.Struct(new(ropc.ROPC), "*"),
wire.Struct(new(devicecode.DeviceCode), "*"),
wire.Struct(new(clientcredentials.ClientCredentials), "*"),
)
type Interface interface {
@@ -34,15 +36,14 @@ type Input struct {
GrantOptionSet GrantOptionSet
CachedTokenSet *oidc.TokenSet // optional
TLSClientConfig tlsclientconfig.Config
ForceRefresh bool
UseAccessToken bool
}
type GrantOptionSet struct {
AuthCodeBrowserOption *authcode.BrowserOption
AuthCodeKeyboardOption *authcode.KeyboardOption
ROPCOption *ropc.Option
DeviceCodeOption *devicecode.Option
AuthCodeBrowserOption *authcode.BrowserOption
AuthCodeKeyboardOption *authcode.KeyboardOption
ROPCOption *ropc.Option
DeviceCodeOption *devicecode.Option
ClientCredentialsOption *client.GetTokenByClientCredentialsInput
}
// Output represents an output DTO of the Authentication use-case.
@@ -54,7 +55,7 @@ type Output struct {
//
// If the IDToken is not set, it performs the authentication flow.
// If the IDToken is valid, it does nothing.
// If the IDtoken has expired and the RefreshToken is set, it refreshes the token.
// If the IDToken has expired and the RefreshToken is set, it refreshes the token.
// If the RefreshToken has expired, it performs the authentication flow.
//
// The authentication flow is determined as:
@@ -63,12 +64,13 @@ type Output struct {
// Otherwise, it performs the resource owner password credentials flow.
// If the Password is not set, it asks a password by the prompt.
type Authentication struct {
ClientFactory client.FactoryInterface
Logger logger.Interface
AuthCodeBrowser *authcode.Browser
AuthCodeKeyboard *authcode.Keyboard
ROPC *ropc.ROPC
DeviceCode *devicecode.DeviceCode
ClientFactory client.FactoryInterface
Logger logger.Interface
AuthCodeBrowser *authcode.Browser
AuthCodeKeyboard *authcode.Keyboard
ROPC *ropc.ROPC
DeviceCode *devicecode.DeviceCode
ClientCredentials *clientcredentials.ClientCredentials
}
func (u *Authentication) Do(ctx context.Context, in Input) (*Output, error) {
@@ -115,5 +117,12 @@ func (u *Authentication) Do(ctx context.Context, in Input) (*Output, error) {
}
return &Output{TokenSet: *tokenSet}, nil
}
if in.GrantOptionSet.ClientCredentialsOption != nil {
tokenSet, err := u.ClientCredentials.Do(ctx, in.GrantOptionSet.ClientCredentialsOption, oidcClient)
if err != nil {
return nil, fmt.Errorf("client-credentials error: %w", err)
}
return &Output{TokenSet: *tokenSet}, nil
}
return nil, fmt.Errorf("any authorization grant must be set")
}

View File

@@ -11,10 +11,12 @@ import (
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/oidc/client_mock"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client"
"github.com/int128/kubelogin/pkg/pkce"
testingJWT "github.com/int128/kubelogin/pkg/testing/jwt"
testingLogger "github.com/int128/kubelogin/pkg/testing/logger"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/authentication/clientcredentials"
"github.com/int128/kubelogin/pkg/usecases/authentication/ropc"
"github.com/stretchr/testify/mock"
)
@@ -96,9 +98,7 @@ func TestAuthentication_Do(t *testing.T) {
},
}
mockClient := client_mock.NewMockInterface(t)
mockClient.EXPECT().
SupportedPKCEMethods().
Return(nil)
mockClient.EXPECT().NegotiatedPKCEMethod().Return(pkce.NoMethod)
mockClient.EXPECT().
Refresh(ctx, "EXPIRED_REFRESH_TOKEN").
Return(nil, errors.New("token has expired"))
@@ -182,4 +182,45 @@ func TestAuthentication_Do(t *testing.T) {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
t.Run("NoToken/ClientCredentials", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
ccIn := client.GetTokenByClientCredentialsInput{
EndpointParams: map[string][]string{
"audience": []string{"gopher://myaud"},
},
}
in := Input{Provider: dummyProvider,
TLSClientConfig: dummyTLSClientConfig,
GrantOptionSet: GrantOptionSet{ClientCredentialsOption: &ccIn}}
testToken := &oidc.TokenSet{IDToken: "TEST_ID_TOKEN"}
mockClient := client_mock.NewMockInterface(t)
mockClient.EXPECT().
GetTokenByClientCredentials(ctx, ccIn).Return(testToken, nil).Once()
mockClientFactory := client_mock.NewMockFactoryInterface(t)
mockClientFactory.EXPECT().
New(ctx, dummyProvider, dummyTLSClientConfig).
Return(mockClient, nil)
u := Authentication{
ClientFactory: mockClientFactory,
Logger: testingLogger.New(t),
ClientCredentials: &clientcredentials.ClientCredentials{
Logger: testingLogger.New(t),
},
}
got, err := u.Do(ctx, in)
if err != nil {
t.Errorf("Do returned error: %+v", err)
}
want := &Output{
TokenSet: oidc.TokenSet{
IDToken: "TEST_ID_TOKEN",
},
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
}

View File

@@ -0,0 +1,28 @@
package clientcredentials
import (
"context"
"fmt"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client"
)
// DeviceCode provides the oauth2 device code flow.
type ClientCredentials struct {
Logger logger.Interface
}
func (u *ClientCredentials) Do(ctx context.Context, in *client.GetTokenByClientCredentialsInput, oidcClient client.Interface) (*oidc.TokenSet, error) {
u.Logger.V(1).Infof("starting the oauth2 client credentials code flow")
if in == nil {
return nil, fmt.Errorf("nil input")
}
tokenSet, err := oidcClient.GetTokenByClientCredentials(ctx, *in)
if err != nil {
return nil, fmt.Errorf("authorization error: %w", err)
}
u.Logger.V(1).Infof("finished the oauth2 client credentials code flow")
return tokenSet, nil
}

View File

@@ -0,0 +1,50 @@
package clientcredentials
import (
"context"
"errors"
"testing"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/oidc/client_mock"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client"
"github.com/int128/kubelogin/pkg/testing/logger"
)
func TestClientCredentials(t *testing.T) {
ctx := context.TODO()
t.Run("Authorization error", func(t *testing.T) {
mockClient := client_mock.NewMockInterface(t)
cc := &ClientCredentials{
Logger: logger.New(t),
}
errTest := errors.New("make sure Do() passes err")
in := client.GetTokenByClientCredentialsInput{}
mockClient.EXPECT().GetTokenByClientCredentials(ctx, in).Return(nil, errTest).Once()
opts := client.GetTokenByClientCredentialsInput{}
_, err := cc.Do(ctx, &opts, mockClient)
if !errors.Is(err, errTest) {
t.Errorf("returned error is not the test error: %v", err)
}
})
t.Run("Server returns access_token", func(t *testing.T) {
mockClient := client_mock.NewMockInterface(t)
cc := &ClientCredentials{
Logger: logger.New(t),
}
in := client.GetTokenByClientCredentialsInput{}
testToken := &oidc.TokenSet{}
mockClient.EXPECT().GetTokenByClientCredentials(ctx, in).Return(testToken, nil).Once()
opts := client.GetTokenByClientCredentialsInput{}
ts, err := cc.Do(ctx, &opts, mockClient)
if err != nil {
t.Errorf("returned unexpected error: %v", err)
}
if ts != testToken {
t.Errorf("returned unexpected token set: %v", ts)
}
})
}

View File

@@ -0,0 +1,47 @@
package clean
import (
"context"
"fmt"
"github.com/google/wire"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/tokencache"
"github.com/int128/kubelogin/pkg/tokencache/repository"
)
var Set = wire.NewSet(
wire.Struct(new(Clean), "*"),
wire.Bind(new(Interface), new(*Clean)),
)
type Interface interface {
Do(ctx context.Context, in Input) error
}
// Input represents an input of the Clean use-case.
type Input struct {
TokenCacheDir string
}
type Clean struct {
TokenCacheRepository repository.Interface
Logger logger.Interface
}
func (u *Clean) Do(ctx context.Context, in Input) error {
u.Logger.V(1).Infof("Deleting the token cache")
if err := u.TokenCacheRepository.DeleteAll(tokencache.Config{Directory: in.TokenCacheDir, Storage: tokencache.StorageDisk}); err != nil {
return fmt.Errorf("delete the token cache from %s: %w", in.TokenCacheDir, err)
}
u.Logger.Printf("Deleted the token cache from %s", in.TokenCacheDir)
if err := u.TokenCacheRepository.DeleteAll(tokencache.Config{Directory: in.TokenCacheDir, Storage: tokencache.StorageKeyring}); err != nil {
// Do not return an error because the keyring may not be available.
u.Logger.Printf("Could not delete the token cache from the keyring: %s", err)
} else {
u.Logger.Printf("Deleted the token cache from the keyring")
}
return nil
}

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