From 272aa5a7fe190c86933b9511b91cda10bcc589a8 Mon Sep 17 00:00:00 2001 From: fcaps Date: Mon, 13 Nov 2023 02:04:40 +0100 Subject: [PATCH] oauth m2m prototype --- example.js | 57 ++++++++++++++++++++++++++++++++ lib/OauthClient.js | 45 ++++++++++++++++++++++++++ package.json | 3 +- yarn.lock | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 example.js create mode 100644 lib/OauthClient.js diff --git a/example.js b/example.js new file mode 100644 index 00000000..60222f2b --- /dev/null +++ b/example.js @@ -0,0 +1,57 @@ +// this is only working if you "fix" the java-api with the workaround described in https://github.com/FAForever/website/issues/445#issuecomment-1798194886 +// you also need to add the new hydra-client into the db (grant_type=client_credentials and token_endpoint_auth_method=client_secret_basic are the changes) + + +// INSERT INTO hydra.hydra_client (id, client_name, client_secret, redirect_uris, grant_types, response_types, scope, +// owner, policy_uri, tos_uri, client_uri, logo_uri, contacts, client_secret_expires_at, +// sector_identifier_uri, jwks, jwks_uri, request_uris, token_endpoint_auth_method, +// request_object_signing_alg, userinfo_signed_response_alg, subject_type, +// allowed_cors_origins, audience, created_at, updated_at, frontchannel_logout_uri, +// frontchannel_logout_session_required, post_logout_redirect_uris, backchannel_logout_uri, +// backchannel_logout_session_required, metadata, token_endpoint_auth_signing_alg, +// authorization_code_grant_access_token_lifespan, +// authorization_code_grant_id_token_lifespan, +// authorization_code_grant_refresh_token_lifespan, +// client_credentials_grant_access_token_lifespan, implicit_grant_access_token_lifespan, +// implicit_grant_id_token_lifespan, jwt_bearer_grant_access_token_lifespan, +// password_grant_access_token_lifespan, password_grant_refresh_token_lifespan, +// refresh_token_grant_id_token_lifespan, refresh_token_grant_access_token_lifespan, +// refresh_token_grant_refresh_token_lifespan, registration_access_token_signature) +// VALUES ('faf-website-m2m', 'faforever.com', '$2a$10$uTc3uuPAS2C7rzD0L6TAlOrjaC/oIvA.jAIcezhOGm4SkSuu55GqC', '', +// 'client_credentials', 'code', '', '100', '', '', '', 'https://faforever.com/images/faf-logo.png', '', 0, '', +// '{}', '', '', 'client_secret_basic', '', 'none', 'public', '', '', '2023-10-27 09:29:17', '2023-10-27 09:29:17', +// '', 0, '', '', 0, '{}', '', null, null, null, null, null, null, null, null, null, null, null, null, +// 'LXDpX3iDiLBFU3LlJzogCPEoF3HiPkD02BZQC-e1cOc'); + +// this is how the result should look like: +// root@fdc4cb2005f8:/code# node example.js +// { +// createTime: '2023-10-27T10:38:46Z', +// description: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr', +// name: 'Alpha Clan', +// requiresInvitation: true, +// tag: 'ALF', +// tagColor: null, +// updateTime: '2023-11-04T05:54:52Z', +// websiteUrl: 'http://localhost:8096/clan/1' +// } + +(async function() { + const {createClient} = require("./lib/OauthClient"); + + const oauthM2mClientId = 'faf-website-m2m' + const oauthM2mClientSecret = 'banana' + const oauthHost = 'http://faf-ory-hydra:4444' + const scope = '' + const javaApiHost = 'http://faf-java-api:8010' + + try { + const oauthServerClient = await createClient(oauthM2mClientId, oauthM2mClientSecret, oauthHost, scope) + const response = await oauthServerClient.get(javaApiHost + '/data/clan') + let clansResponse = Object.values(response.data); + + console.log(clansResponse[0][0].attributes) + } catch (e) { + console.error(e.toString()) + } +})() diff --git a/lib/OauthClient.js b/lib/OauthClient.js new file mode 100644 index 00000000..944b6019 --- /dev/null +++ b/lib/OauthClient.js @@ -0,0 +1,45 @@ +const {ClientCredentials} = require("simple-oauth2"); +const axios = require("axios"); + +const getToken = async function(clientId, clientSecret, host, scope) { + const tokenClient = new ClientCredentials({ + client: { + id: clientId, + secret: clientSecret, + + }, + auth: { + tokenHost: host, + tokenPath: '/oauth2/token', + revokePath: '/oauth2/revoke' + } + }) + + try { + return tokenClient.getToken({ + scope: scope ?? '', + }) + } catch (error) { + console.error('[error] oauthClient::getToken', error.message); + + return null + } +} + +const createClient = async function(clientId, clientSecret, host, scope) { + let token= await getToken(clientId, clientSecret, host, scope) + const instance = await axios.create(); + + instance.interceptors.request.use(config => { + if (token.expired()) { + token = token.refresh() + } + + config.headers['Authorization'] = `Bearer ${token.token.access_token}`; + return config; + }); + + return instance +} + +exports.createClient = createClient diff --git a/package.json b/package.json index 4bed14cd..f942676a 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "passport-openidconnect": "^0.1.1", "pug": "3.0.2", "request": "2.88.2", - "showdown": "^2.1.0" + "showdown": "^2.1.0", + "simple-oauth2": "^5.0.0" }, "devDependencies": { "awesomplete": "^1.1.5", diff --git a/yarn.lock b/yarn.lock index 675794c6..1346266c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -112,6 +112,49 @@ dependencies: stackframe "^1.1.1" +"@hapi/boom@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-10.0.1.tgz#ebb14688275ae150aa6af788dbe482e6a6062685" + integrity sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA== + dependencies: + "@hapi/hoek" "^11.0.2" + +"@hapi/bourne@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-3.0.0.tgz#f11fdf7dda62fe8e336fa7c6642d9041f30356d7" + integrity sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w== + +"@hapi/hoek@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-10.0.1.tgz#ee9da297fabc557e1c040a0f44ee89c266ccc306" + integrity sha512-CvlW7jmOhWzuqOqiJQ3rQVLMcREh0eel4IBnxDx2FAcK8g7qoJRQK4L1CPBASoCY6y8e6zuCy3f2g+HWdkzcMw== + +"@hapi/hoek@^11.0.2": + version "11.0.2" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-11.0.2.tgz#cb3ea547daac7de5c9cf1d960c3f35c34f065427" + integrity sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw== + +"@hapi/hoek@^9.0.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" + integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== + +"@hapi/topo@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@hapi/wreck@^18.0.0": + version "18.0.1" + resolved "https://registry.yarnpkg.com/@hapi/wreck/-/wreck-18.0.1.tgz#6df04532be25fd128c5244e72ccc21438cf8bb65" + integrity sha512-OLHER70+rZxvDl75xq3xXOfd3e8XIvz8fWY0dqg92UvhZ29zo24vQgfqgHSYhB5ZiuFpSLeriOisAlxAo/1jWg== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/bourne" "^3.0.0" + "@hapi/hoek" "^11.0.2" + "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" @@ -170,6 +213,23 @@ resolved "https://registry.yarnpkg.com/@servie/events/-/events-1.0.0.tgz#8258684b52d418ab7b86533e861186638ecc5dc1" integrity sha512-sBSO19KzdrJCM3gdx6eIxV8M9Gxfgg6iDQmH5TIAGaUu+X9VDdsINXJOnoiZ1Kx3TrHdH4bt5UVglkjsEGBcvw== +"@sideway/address@^4.1.3": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" + integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -3057,6 +3117,17 @@ jit-grunt@0.10.0: resolved "https://registry.yarnpkg.com/jit-grunt/-/jit-grunt-0.10.0.tgz#008c3a7fe1e96bd0d84e260ea1fa1783457f79c2" integrity sha512-eT/f4c9wgZ3buXB7X1JY1w6uNtAV0bhrbOGf/mFmBb0CDNLUETJ/VRoydayWOI54tOoam0cz9RooVCn3QY1WoA== +joi@^17.6.4: + version "17.11.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.11.0.tgz#aa9da753578ec7720e6f0ca2c7046996ed04fc1a" + integrity sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.3" + "@sideway/formula" "^3.0.1" + "@sideway/pinpoint" "^2.0.0" + js-base64@^2.1.9: version "2.6.4" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" @@ -5087,6 +5158,16 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-oauth2@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/simple-oauth2/-/simple-oauth2-5.0.0.tgz#3b7d85700944b26f8f5451c017426292f330460c" + integrity sha512-8291lo/z5ZdpmiOFzOs1kF3cxn22bMj5FFH+DNUppLJrpoIlM1QnFiE7KpshHu3J3i21TVcx4yW+gXYjdCKDLQ== + dependencies: + "@hapi/hoek" "^10.0.1" + "@hapi/wreck" "^18.0.0" + debug "^4.3.4" + joi "^17.6.4" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"