Skip to content

Commit

Permalink
STCOR-946: set tenant context based on authentication response with o…
Browse files Browse the repository at this point in the history
…verrideUser parameter on login
  • Loading branch information
aidynoJ committed Feb 20, 2025
1 parent 66132af commit 328aae1
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 16 deletions.
49 changes: 35 additions & 14 deletions src/loginServices.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import localforage from 'localforage';
import { config, translations } from 'stripes-config';
import { config, okapi, translations } from 'stripes-config';
import rtlDetect from 'rtl-detect';
import moment from 'moment';
import { loadDayJSLocale } from '@folio/stripes-components';
Expand Down Expand Up @@ -400,12 +400,12 @@ function loadResources(store, tenant, userId) {
// in mod-configuration so we can only retrieve them if the user has
// read-permission for configuration entries.
if (canReadConfig(store)) {
const okapi = store.getState()?.okapi;
const okapiObject = store.getState()?.okapi;
promises = [
getLocale(okapi.url, store, tenant),
getUserLocale(okapi.url, store, tenant, userId),
getPlugins(okapi.url, store, tenant),
getBindings(okapi.url, store, tenant),
getLocale(okapiObject.url, store, tenant),
getUserLocale(okapiObject.url, store, tenant, userId),
getPlugins(okapiObject.url, store, tenant),
getBindings(okapiObject.url, store, tenant),
];
}

Expand Down Expand Up @@ -594,7 +594,7 @@ export function createOkapiSession(store, tenant, token, data) {
rtExpires: data.tokenExpiration?.refreshTokenExpiration ? new Date(data.tokenExpiration.refreshTokenExpiration).getTime() : Date.now() + (10 * 60 * 1000),
};

const sessionTenant = data.tenant || tenant;
const sessionTenant = data.originalTenantId || data.tenant || tenant;
const okapiSess = {
token,
isAuthenticated: true,
Expand Down Expand Up @@ -891,17 +891,16 @@ export function requestLogin(okapiUrl, store, tenant, data) {

/**
* fetchUserWithPerms
* retrieve currently-authenticated user
* retrieve currently-authenticated user data after switching affiliation
* @param {string} okapiUrl
* @param {string} tenant
* @param {string} token
* @param {boolean} rtrIgnore
* @param {boolean} isKeycloak
*
* @returns {Promise} Promise resolving to the response of the request
*/
function fetchUserWithPerms(okapiUrl, tenant, token, rtrIgnore = false, isKeycloak = false) {
const usersPath = isKeycloak ? 'users-keycloak' : 'bl-users';
function fetchUserWithPerms(okapiUrl, tenant, token, rtrIgnore = false) {
const usersPath = okapi.authnUrl ? 'users-keycloak' : 'bl-users';
return fetch(
`${okapiUrl}/${usersPath}/_self?expandPermissions=true&fullPermissions=true`,
{
Expand All @@ -911,6 +910,29 @@ function fetchUserWithPerms(okapiUrl, tenant, token, rtrIgnore = false, isKeyclo
);
}

/**
* fetchOverriddenUserWithPerms
* Query string parameter overrideUser is set to true the retrieved shadow user will be used to fetch the real user together with its permissions and service points.
* After fetching process begin a session.
* @param {string} okapiUrl
* @param {redux store} store
* @param {string} tenant
* @param {string} token
*
* @returns {Promise} Promise resolving to the response-body (JSON) of the request
*/

function fetchOverriddenUserWithPerms(okapiUrl, tenant, token, rtrIgnore = false) {
const usersPath = okapi.authnUrl ? 'users-keycloak' : 'bl-users';
return fetch(
`${okapiUrl}/${usersPath}/_self?expandPermissions=true&fullPermissions=true&overrideUser=true`,
{
headers: getHeaders(tenant, token),
rtrIgnore,
},
);
}

/**
* requestUserWithPerms
* retrieve currently-authenticated user, then process the result to begin a session.
Expand All @@ -922,8 +944,7 @@ function fetchUserWithPerms(okapiUrl, tenant, token, rtrIgnore = false, isKeyclo
* @returns {Promise} Promise resolving to the response-body (JSON) of the request
*/
export function requestUserWithPerms(okapiUrl, store, tenant, token) {
const isKeycloak = Boolean(store.getState().okapi?.authnUrl);
return fetchUserWithPerms(okapiUrl, tenant, token, !token, isKeycloak)
return fetchOverriddenUserWithPerms(okapiUrl, tenant, token, !token)
.then((resp) => {
if (resp.ok) {
return processOkapiSession(store, tenant, resp, token);
Expand Down Expand Up @@ -989,7 +1010,7 @@ export function updateUser(store, data) {
*/
export async function updateTenant(okapiConfig, tenant) {
const okapiSess = await getOkapiSession();
const userWithPermsResponse = await fetchUserWithPerms(okapiConfig.url, tenant, okapiConfig.token, false, Boolean(okapiConfig.authnUrl));
const userWithPermsResponse = await fetchUserWithPerms(okapiConfig.url, tenant, okapiConfig.token, false);
const userWithPerms = await userWithPermsResponse.json();
await localforage.setItem(SESSION_NAME, { ...okapiSess, tenant, ...spreadUserWithPerms(userWithPerms) });
}
39 changes: 37 additions & 2 deletions src/loginServices.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
validateUser,
IS_LOGGING_OUT,
SESSION_NAME, getStoredTenant,
requestLogin,
requestLogin, requestUserWithPerms,
} from './loginServices';

import {
Expand Down Expand Up @@ -63,6 +63,9 @@ jest.mock('stripes-config', () => ({
remus: { name: 'remus', clientId: 'remus-application' },
}
},
okapi: {
authnUrl: 'https://authn.url',
},
translations: {}
}));

Expand All @@ -85,7 +88,7 @@ const mockFetchError = (error) => {

// restore default fetch impl
const mockFetchCleanUp = () => {
global.fetch.mockClear();
global.fetch?.mockClear();
delete global.fetch;
};

Expand Down Expand Up @@ -765,4 +768,36 @@ describe('unauthorizedPath functions', () => {
);
});
});

describe('requestUserWithPerms', () => {
afterEach(() => {
mockFetchCleanUp();
});
it('should authenticate and create session when valid credentials provided', async () => {
mockFetchSuccess({ tenant:'tenant', originalTenantId:'originalTenantId' });
const mockStore = {
getState: () => ({
okapi: {},
}),
dispatch: jest.fn()
};

await requestUserWithPerms(
'http://okapi-url',
mockStore,
'test-tenant',
'token'
);

expect(global.fetch).toHaveBeenCalledWith('http://okapi-url/users-keycloak/_self?expandPermissions=true&fullPermissions=true&overrideUser=true',
{
headers: expect.objectContaining({
'X-Okapi-Tenant': 'test-tenant',
'X-Okapi-Token': 'token',
'Content-Type': 'application/json',
}),
'rtrIgnore': false
});
});
});
});

0 comments on commit 328aae1

Please sign in to comment.