Skip to content

Commit

Permalink
use authorization check to determine launch provider access
Browse files Browse the repository at this point in the history
Signed-off-by: aporss <[email protected]>
  • Loading branch information
ArtjomsPorss committed Nov 21, 2024
1 parent ef2a5b0 commit 25e95f2
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 61 deletions.
12 changes: 6 additions & 6 deletions ui/src/__tests__/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('Fetchr Client API Test', () => {
describe('listUserDomains test', () => {
it('listUserDomains test success', async () => {
myDataService = {
name: 'domain-role-member',
name: 'domain-list',
read: function (req, resource, params, config, callback) {
callback(null, DATA);
},
Expand All @@ -39,7 +39,7 @@ describe('Fetchr Client API Test', () => {
});
it('listUserDomains test error', async () => {
myDataServiceErr = {
name: 'domain-role-member',
name: 'domain-list',
read: function (req, resource, params, config, callback) {
callback({}, null);
},
Expand Down Expand Up @@ -1189,26 +1189,26 @@ describe('Fetchr Client API Test', () => {
describe('getProvider test', () => {
it('getProvider test success', async () => {
myDataService = {
name: 'provider',
name: 'access',
read: function (req, resource, params, config, callback) {
callback(null, DATA);
},
};
fetchrStub = sinon.stub(Fetchr, 'isRegistered');
fetchrStub.returns(myDataService);
result = await api.getProvider('dummyDom', 'dummySvc');
result = await api.getProviderAccess('dummyDom', 'dummySvc');
expect(result).toEqual(DATA);
});
it('getProvider test error', async () => {
myDataServiceErr = {
name: 'provider',
name: 'access',
read: function (req, resource, params, config, callback) {
return callback({}, null);
},
};
fetchrStub = sinon.stub(Fetchr, 'isRegistered');
fetchrStub.returns(myDataServiceErr);
await api.getProvider('dummyDom', 'dummySvc').catch((err) => {
await api.getProviderAccess('dummyDom', 'dummySvc').catch((err) => {
expect(err).not.toBeNull();
});
});
Expand Down
4 changes: 3 additions & 1 deletion ui/src/__tests__/components/service/ServiceRow.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ describe('ServiceRow', () => {
getServices: jest
.fn()
.mockReturnValue(Promise.resolve([{ name: fullServiceName }])),
getProvider: jest.fn().mockReturnValue(Promise.resolve(toReturn)),
getProviderAccess: jest
.fn()
.mockReturnValue(Promise.resolve(toReturn)),
};
MockApi.setMockApi(api);
const color = '';
Expand Down
8 changes: 5 additions & 3 deletions ui/src/__tests__/redux/thunk/services.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -627,20 +627,22 @@ describe('getProvider method', () => {
provider: {},
});
let myMockApi = {
getProvider: jest
getProviderAccess: jest
.fn()
.mockReturnValue(
Promise.resolve({ provider: {}, allProviders: [] })
),
};
MockApi.setMockApi(myMockApi);
sinon.spy(myMockApi, 'getProvider');
sinon.spy(myMockApi, 'getProviderAccess');
const fakeDispatch = sinon.spy();
const getState = () => {};
await getProvider(domainName, 'service1')(fakeDispatch, getState);
expect(fakeDispatch.getCall(0).args[0]).toBeTruthy();
expect(
myMockApi.getProvider.getCall(0).calledWith(domainName, 'service1')
myMockApi.getProviderAccess
.getCall(0)
.calledWith(domainName, 'service1')
).toBeTruthy();
expect(fakeDispatch.getCall(1).args[0]).toEqual(
loadProvidersToStore('dom.service1', {}, [])
Expand Down
39 changes: 12 additions & 27 deletions ui/src/__tests__/server/handlers/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const config = {
{
id: 'aws_instance_launch_provider',
name: 'AWS EC2/EKS/Fargate launches instances for the service',
service: 'athens.aws.us-east-1',
},
],
createDomainMessage: '',
Expand All @@ -43,10 +44,6 @@ const secrets = {};
const expressApp = require('express')();
const request = require('supertest');
const bodyParser = require('body-parser');
const {
listUserDomains_response,
getPrincipalRoles_response,
} = require('../../../mock/MockData');

describe('Fetchr Server API Test', () => {
describe('success tests', () => {
Expand Down Expand Up @@ -87,24 +84,6 @@ describe('Fetchr Server API Test', () => {
params.forcefail
? callback({ status: 404 }, null)
: callback(undefined, { success: 'true' }),
getPrincipalRoles: (params, callback) => {
if (
params.principal &&
params.principal !=
`${config.userDomain}.testuser`
) {
// If the specified member is not included in any role in all domains, an empty array is responded.
callback(undefined, {
memberRoles: [],
});
return;
}
params.forcefail
? callback({ status: 404 }, null)
: callback(undefined, {
...getPrincipalRoles_response,
});
},
putDomainTemplate: (params, callback) =>
params.forcefail
? callback({ status: 404 }, null)
Expand Down Expand Up @@ -163,6 +142,8 @@ describe('Fetchr Server API Test', () => {
params.forcefail
? callback({ status: 404 }, null)
: callback(undefined, { success: 'true' }),
getAccessExt: (params, callback) =>
callback(undefined, { granted: 'true' }),
putPolicy: (params, callback) =>
params.forcefail
? callback({ status: 404 }, null)
Expand Down Expand Up @@ -556,9 +537,12 @@ describe('Fetchr Server API Test', () => {
});
it('domainList test success', async () => {
await request(expressApp)
.get('/api/v1/domain-role-member')
.get('/api/v1/domain-list')
.then((res) => {
expect(res.body).toEqual(listUserDomains_response);
expect(res.body).toEqual([
{ adminDomain: true, name: 'dom1' },
{ adminDomain: true, name: 'domabc1' },
]);
});
});
it('getForm test success', async () => {
Expand Down Expand Up @@ -734,18 +718,19 @@ describe('Fetchr Server API Test', () => {
expect(res.body.g0.data).toEqual({ success: 'true' });
});
});
it('getProvider test success', async () => {
it('getAccessExt test granted - true', async () => {
await request(expressApp)
.get('/api/v1/provider')
.get('/api/v1/access')
.then((res) => {
expect(res.body).toEqual({
allProviders: [
{
id: 'aws_instance_launch_provider',
name: 'AWS EC2/EKS/Fargate launches instances for the service',
service: 'athens.aws.us-east-1',
},
],
provider: { aws_instance_launch_provider: 'not' },
provider: { aws_instance_launch_provider: 'allow' },
});
});
});
Expand Down
10 changes: 5 additions & 5 deletions ui/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ const Api = (req) => {
return undefined;
},

listUserDomains() {
listUserDomains(roleName) {
return new Promise((resolve, reject) => {
fetchr
.read('domain-role-member')
.params({ expand: true })
.read('domain-list')
.params({ roleName })
.end((err, data) => {
if (err) {
reject(err);
Expand Down Expand Up @@ -1058,10 +1058,10 @@ const Api = (req) => {
});
},

getProvider(domainName, serviceName) {
getProviderAccess(domainName, serviceName) {
return new Promise((resolve, reject) => {
fetchr
.read('provider')
.read('access')
.params({ domainName, serviceName })
.end((err, data) => {
if (err) {
Expand Down
1 change: 1 addition & 0 deletions ui/src/config/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ const config = {
{
id: 'aws_instance_launch_provider',
name: 'AWS EC2/EKS/Fargate launches instances for the service',
service: 'athens.aws.us-east-1',
},
],
createDomainMessage:
Expand Down
4 changes: 1 addition & 3 deletions ui/src/pages/domain/[domain]/group/[group]/roles.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ import GroupTabs from '../../../../../components/header/GroupTabs';
import GroupRoleTable from '../../../../../components/group/GroupRoleTable';
import SearchInput from '../../../../../components/denali/SearchInput';
import { getDomainData } from '../../../../../redux/thunks/domain';
import {
getGroup,
} from '../../../../../redux/thunks/groups';
import { getGroup } from '../../../../../redux/thunks/groups';
import { connect } from 'react-redux';
import { selectIsLoading } from '../../../../../redux/selectors/loading';
import {
Expand Down
5 changes: 4 additions & 1 deletion ui/src/redux/thunks/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,10 @@ export const getProvider =
return Promise.resolve();
} else {
try {
let data = await API().getProvider(domainName, serviceName);
let data = await API().getProviderAccess(
domainName,
serviceName
);
dispatch(
loadProvidersToStore(
getFullName(domainName, serviceDelimiter, serviceName),
Expand Down
26 changes: 11 additions & 15 deletions ui/src/server/handlers/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ Fetchr.registerService({
});

Fetchr.registerService({
name: 'provider',
name: 'access',
read(req, resource, params, config, callback) {
let res = {
provider: {},
Expand All @@ -1088,29 +1088,21 @@ Fetchr.registerService({
const service = `${params.domainName}:service.${params.serviceName}`;
appConfig.allProviders.forEach((provider) => {
let param = {
domainName: params.domainName,
policyName: provider.id,
domain: params.domainName,
resource: service,
checkPrincipal: provider.service,
action: 'launch',
};
promises.push(
new Promise((resolve, reject) => {
req.clients.zms.getPolicy(param, (err, data) => {
req.clients.zms.getAccessExt(param, (err, data) => {
res.provider[provider.id] = 'not';
if (err) {
if (err.status !== 404) {
reject(err);
}
}
if (
data &&
data.assertions &&
data.assertions.some(
(a) =>
a.resource &&
a.resource === service &&
a.action &&
a.action === 'launch'
)
) {
if (data && data.granted) {
res.provider[provider.id] = 'allow';
}
resolve();
Expand All @@ -1133,6 +1125,10 @@ Fetchr.registerService({
callback(errorHandler.fetcherError(err));
});
},
});

Fetchr.registerService({
name: 'provider',
create(req, resource, params, body, config, callback) {
req.clients.zms.putDomainTemplate(
params,
Expand Down

0 comments on commit 25e95f2

Please sign in to comment.