Skip to content

Commit

Permalink
Fixing OpenID Connect (#215)
Browse files Browse the repository at this point in the history
🐛 fixed OIDC fetch requests
🐛 added OIDC service registration + async update for settings
  • Loading branch information
the-markus authored Aug 20, 2024
1 parent c0f6bb8 commit d4b6b09
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 57 deletions.
24 changes: 18 additions & 6 deletions imports/api/globalsettings/server/methods.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ValidatedMethod } from 'meteor/mdg:validated-method'
import { defaultSettings, Globalsettings } from '../globalsettings.js'
import { adminAuthenticationMixin, transactionLogMixin } from '../../../utils/server_method_helpers.js'
import { Oidc } from '../../../utils/oidc/oidc_server.js'

/**
@summary Updates global settings
Expand Down Expand Up @@ -75,11 +76,22 @@ const updateOidcSettings = new ValidatedMethod({
check(configuration, Object)
},
mixins: [adminAuthenticationMixin, transactionLogMixin],
async run({ configuration }) {
await ServiceConfiguration.configurations.removeAsync({
service: 'oidc',
})
await ServiceConfiguration.configurations.insertAsync(configuration)
async run({ configuration }) {
if(configuration.secret && configuration.secret.length > 0) {
try {
await Oidc.registerOidc()
} catch (ignored) {}
} else {
delete configuration.secret
}

for (const [key, value] of Object.entries(configuration)) {
await ServiceConfiguration.configurations.updateAsync({ service: 'oidc' }, {
$set: {
[key]: value,
},
})
}
},
})
/**
Expand All @@ -102,4 +114,4 @@ export {
getGlobalsettingCategories,
updateGlobalSettings,
resetGlobalsetting,
}
}
94 changes: 43 additions & 51 deletions imports/utils/oidc/oidc_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,64 +21,56 @@ async function getConfiguration() {
async function getToken(query) {
const config = await getConfiguration()
const serverTokenEndpoint = `${config.serverUrl}${config.tokenEndpoint}`
let response

try {
response = await fetch(serverTokenEndpoint, {
method: 'POST',
headers: {
'Accept': 'application/json',
'User-Agent': userAgent,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
code: query.code,
client_id: config.clientId,
client_secret: OAuth.openSecret(config.secret),
redirect_uri: OAuth._redirectUri(SERVICE_NAME, config),
grant_type: 'authorization_code',
state: query.state,
})

const request = await fetch(serverTokenEndpoint, {
method: 'POST',
headers: {
'Accept': 'application/json',
'User-Agent': userAgent,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
code: query.code,
client_id: config.clientId,
client_secret: OAuth.openSecret(config.secret),
redirect_uri: OAuth._redirectUri(SERVICE_NAME, config),
grant_type: 'authorization_code',
state: query.state,
})
} catch (err) {
const error = new Error(`Failed to get token from OIDC ${serverTokenEndpoint}: ${err.message}`)
error.response = err.response
throw error
}
if (response.data.error) {
// if the http response was a json object with an error attribute
throw new Error(`Failed to complete handshake with OIDC ${serverTokenEndpoint}: ${response.data.error}`)
});

const response = await request.json();

if(response.error) {
throw new Error(`Failed to get token from OIDC ${serverTokenEndpoint}: ${response.error}`);
} else {
return response.data
return response;
}
}

async function getUserInfoFromEndpoint(accessToken, config, expiresAt) {
const serverUserinfoEndpoint = `${config.serverUrl}${config.userinfoEndpoint}`
let response
try {
response = await fetch(serverUserinfoEndpoint, {
method: 'GET',
headers: {
'User-Agent': userAgent,
'Authorization': `Bearer ${accessToken}`,
},
})
} catch (err) {
const error = new Error(`Failed to fetch userinfo from OIDC ${serverUserinfoEndpoint}: ${err.message}`)
error.response = err.response
throw error
}
const request = await fetch(serverUserinfoEndpoint, {
method: 'GET',
headers: {
'User-Agent': userAgent,
'Authorization': `Bearer ${accessToken}`,
},
});

const userinfo = response.data
return {
id: userinfo.id || userinfo.sub,
username: userinfo.username || userinfo.preferred_username,
accessToken: OAuth.sealSecret(accessToken),
expiresAt,
email: userinfo.email,
name: userinfo.name,
}
const response = await request.json();

if(response.error) {
throw new Error(`Failed to get userinfo from OIDC ${serverUserinfoEndpoint}: ${response.error}`);
} else
return {
id: response.id || response.sub,
username: response.username || response.preferred_username,
accessToken: OAuth.sealSecret(accessToken),
expiresAt,
email: response.email,
name: response.name,
}
}

function getTokenContent(token) {
Expand Down Expand Up @@ -156,4 +148,4 @@ async function registerOidc() {
}
})
}
export { registerOidc }
export { registerOidc }

0 comments on commit d4b6b09

Please sign in to comment.