Skip to content

Commit

Permalink
Merge branch 'feature/432038-federated-catalog' into 'develop'
Browse files Browse the repository at this point in the history
Feature/432038 federated catalog

See merge request upm-inesdata/inesdata-public-portal-backend!3
  • Loading branch information
ralconada-gmv committed May 27, 2024
2 parents 604585f + 7390e22 commit a790461
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
9 changes: 9 additions & 0 deletions config/inesdata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const path = require('path');

module.exports = ({ env }) => ({
tokenClientId: env('TOKEN_CLIENT_ID', 'dataspace-users'),
tokenUsername: env('TOKEN_USERNAME', 'user-c1'),
tokenPassword: env('TOKEN_PASSWORD', 'user-c1'),
keycloakBaseUrl: env('KEYCLOAK_BASE_URL', 'http://keycloak:8080'),
catalogBaseUrl: env('CATALOG_BASE_URL', 'http://connector-c1:19193')
})
2 changes: 2 additions & 0 deletions config/server.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require('dotenv').config();

module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
Expand Down
117 changes: 117 additions & 0 deletions src/api/get-federated-catalog/controllers/get-federated-catalog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'use strict';

const axios = require('axios');

const tokenData = {
accessToken: null,
refreshToken: null,
expiresIn: null,
refreshExpiresIn: null,
obtainedAt: null,
refreshObtainedAt: null
};

const getTokenFromAuthServer = async () => {
try {
const params = new URLSearchParams();
params.append('grant_type', 'password');
params.append('client_id', process.env.TOKEN_CLIENT_ID);
params.append('username', process.env.TOKEN_USERNAME);
params.append('password', process.env.TOKEN_PASSWORD);

const tokenUrl = `${process.env.KEYCLOAK_BASE_URL}/realms/dataspace/protocol/openid-connect/token`;

const response = await axios.post(tokenUrl, params);
const data = response.data;

tokenData.accessToken = data.access_token;
tokenData.refreshToken = data.refresh_token;
tokenData.expiresIn = data.expires_in; // expires_in is in seconds
tokenData.refreshExpiresIn = data.refresh_expires_in; // refresh_expires_in is in seconds
tokenData.obtainedAt = Date.now(); // store the time the token was obtained
tokenData.refreshObtainedAt = Date.now(); // store the time the refresh token was obtained

return data;
} catch (error) {
console.error('Error obtaining token from auth server:', error);
throw new Error('Failed to obtain token from auth server');
}
};

const refreshToken = async () => {
try {
const params = new URLSearchParams();
params.append('grant_type', 'refresh_token');
params.append('client_id', process.env.TOKEN_CLIENT_ID);
params.append('refresh_token', tokenData.refreshToken);

const tokenUrl = `${process.env.KEYCLOAK_BASE_URL}/realms/dataspace/protocol/openid-connect/token`;

const response = await axios.post(tokenUrl, params);
const data = response.data;

tokenData.accessToken = data.access_token;
tokenData.refreshToken = data.refresh_token;
tokenData.expiresIn = data.expires_in;
tokenData.refreshExpiresIn = data.refresh_expires_in;
tokenData.obtainedAt = Date.now();

return data;
} catch (error) {
console.error('Error refreshing token:', error);
throw new Error('Failed to refresh token');
}
};

const getAccessToken = async () => {
try {
if (!tokenData.accessToken || !tokenData.refreshToken) {
await getTokenFromAuthServer();
} else {
const currentTime = Date.now();
const accessTokenExpired = (currentTime - tokenData.obtainedAt) / 1000 > tokenData.expiresIn;
const refreshTokenExpired = (currentTime - tokenData.refreshObtainedAt) / 1000 > tokenData.refreshExpiresIn;

if (refreshTokenExpired) {
await getTokenFromAuthServer();
} else if (accessTokenExpired) {
await refreshToken();
}
}

return tokenData.accessToken;
} catch (error) {
console.error('Error getting access token:', error);
throw new Error('Failed to get access token');
}
};

module.exports = {
getFederatedCatalog: async (ctx, next) => {
try {
const accessToken = await getAccessToken();
if (!accessToken) {
ctx.body = { message: 'Access token not available. Please authenticate first.' };
ctx.status = 401;
return;
}

// URL for fetching the federated catalog
const catalogUrl = `${process.env.CATALOG_BASE_URL}/management/federatedcatalog`;

// Fetch the federated catalog using the access token
const response = await axios.post(catalogUrl, {}, {
headers: {
Authorization: `Bearer ${accessToken}`
}
});

// Respond with the fetched data
ctx.body = response.data;
} catch (err) {
console.error('Error:', err);
ctx.body = { message: 'Error fetching federated catalog!', details: err.message };
ctx.status = 500;
}
}
};
9 changes: 9 additions & 0 deletions src/api/get-federated-catalog/routes/get-federated-catalog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
"routes": [
{
"method": "GET",
"path": "/get-federated-catalog",
"handler": "get-federated-catalog.getFederatedCatalog"
}
]
};

0 comments on commit a790461

Please sign in to comment.