Skip to content

Commit

Permalink
[CF-447] Use paginated requests (#61)
Browse files Browse the repository at this point in the history
* fix: filter client grants by client & audience

* feat: use paginated requests for resource servers

* version 2.4.1
  • Loading branch information
santiagoaguiar authored Jul 14, 2020
1 parent 98631db commit a0fd0c6
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 13 deletions.
143 changes: 142 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "auth0-sso-dashboard",
"version": "2.4.0",
"version": "2.4.1",
"description": "This extension provides your users with a dashboard for all of their applications.",
"engines": {
"node": ">=4.x"
Expand Down Expand Up @@ -156,6 +156,7 @@
"redux-simple-router": "^2.0.4",
"redux-static": "^1.0.0",
"rimraf": "^2.5.2",
"sinon": "^9.0.2",
"style-loader": "^0.13.1",
"uglifyjs-webpack-plugin": "^1.2.4",
"url-loader": "^1.0.1",
Expand Down
3 changes: 2 additions & 1 deletion server/lib/multipartRequest.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { snakeCase } from 'lodash';
import Promise from 'bluebird';
import { ArgumentError } from 'auth0-extension-tools';

Expand All @@ -21,7 +22,7 @@ export default function (client, entity, opts = {}, perPage = 100, concurrency =
.then((response) => {
total = response.total || 0;
pageCount = Math.ceil(total / perPage);
const data = response[entity] || response || [];
const data = response[entity] || response[snakeCase(entity)] || response || [];
data.forEach(item => result.push(item));
return null;
});
Expand Down
13 changes: 9 additions & 4 deletions server/lib/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { managementApi, ValidationError } from 'auth0-extension-tools';

import config from './config';
import logger from './logger';
import multipartRequest from './multipartRequest';


const getAuthorizationApiUrl = () => {
Expand Down Expand Up @@ -136,12 +137,16 @@ const getToken = (req) => {
const makeRequest = (req, path, method, payload) =>
new Promise((resolve, reject) => getToken(req).then((token) => {
request(method, `https://${config('AUTH0_DOMAIN')}/api/v2/${path}`)
.send(payload || {})
.query(method === 'GET' ? payload : {})
.send(method === 'GET' ? null : payload || {})
.set('Content-Type', 'application/json')
.set('Authorization', `Bearer ${token}`)
.end((err, res) => {
if (err) {
logger.error(res.body);
if (res && res.body) {
logger.error(res.body);
}

return reject(err);
}

Expand All @@ -151,7 +156,7 @@ const makeRequest = (req, path, method, payload) =>
);

export const getResourceServer = (req, audience) =>
makeRequest(req, 'resource-servers', 'GET')
multipartRequest(req.auth0, 'resourceServers')
.then((apis) => {
const api = apis.filter(item => item.identifier === audience);
return api.length && api[0];
Expand Down Expand Up @@ -183,7 +188,7 @@ export const deleteResourceServer = req =>
});

const getGrantId = req =>
makeRequest(req, 'client-grants', 'GET')
makeRequest(req, 'client-grants', 'GET', { client_id: config('AUTH0_CLIENT_ID'), audience: 'urn:auth0-authz-api' })
.then(grants => grants.filter(item => (item.client_id === config('AUTH0_CLIENT_ID') && item.audience === 'urn:auth0-authz-api')))
.then(grants => grants[0] && grants[0].id);

Expand Down
2 changes: 1 addition & 1 deletion server/routes/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default (storage) => {
});
api.use('/applications', applications(auth0, storage));
api.use('/groups', groups(storage));
api.use('/authorization', authorization(storage));
api.use('/authorization', authorization(auth0, storage));
api.use('/connections', connections(auth0));
api.get('/status', (req, res) => {
res.json({ isAdmin: (req.user.scope && req.user.scope.indexOf('manage:applications') > -1) });
Expand Down
8 changes: 4 additions & 4 deletions server/routes/authorization.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import config from '../lib/config';
import * as authorization from '../lib/authorization';
import { requireScope } from '../lib/middlewares';

export default (storage) => {
export default (auth0, storage) => {
const api = Router();

api.get('/', requireScope('manage:authorization'), (req, res, next) => {
api.get('/', auth0, requireScope('manage:authorization'), (req, res, next) => {
if (!config('ALLOW_AUTHZ')) {
return res.json({ authorizationApiAvailable: false });
}
Expand All @@ -17,7 +17,7 @@ export default (storage) => {
.catch(next);
});

api.post('/', requireScope('manage:authorization'), (req, res, next) => {
api.post('/', auth0, requireScope('manage:authorization'), (req, res, next) => {
if (!config('ALLOW_AUTHZ')) {
return next();
}
Expand All @@ -27,7 +27,7 @@ export default (storage) => {
.catch(next);
});

api.delete('/', requireScope('manage:authorization'), (req, res, next) => {
api.delete('/', auth0, requireScope('manage:authorization'), (req, res, next) => {
if (!config('ALLOW_AUTHZ')) {
return next();
}
Expand Down
58 changes: 58 additions & 0 deletions tests/server/lib/queries.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* eslint-disable import/no-extraneous-dependencies */
import { expect } from 'chai';
import sinon from 'sinon';
import nock from 'nock';
import { setProvider } from '../../../server/lib/config';
import { getResourceServer, removeGrant } from '../../../server/lib/queries';

describe('queries', () => {
before(() => {
setProvider(() => 'auth0.example.com');
});

describe('getResourceServer', () => {
it('should fetch the resource servers with pagination', () => {
const req = {
auth0: {
resourceServers: {
getAll: sinon.spy(() => {
return Promise.resolve({ total: 1, resource_servers: [{ identifier: 'http://audience' }] });
})
}
}
};
return getResourceServer(req, 'http://audience').then((resourceServer) => {
expect(resourceServer).to.eql({ identifier: 'http://audience' });
sinon.assert.calledOnce(req.auth0.resourceServers.getAll);
sinon.assert.calledWith(req.auth0.resourceServers.getAll, { include_totals: true, page: 0, per_page: 100 });
});
});
});

describe('removeGrant', () => {
afterEach(() => {
nock.restore();
});

it('should delete the grant if it exists', () => {
const get = nock('https://auth0.example.com')
.get('/api/v2/client-grants')
.query({ client_id: 'auth0.example.com',audience: 'urn:auth0-authz-api' })
.reply(200, [ { client_id: 'auth0.example.com',audience: 'urn:auth0-authz-api', id: 'id1' }]);

const del = nock('https://auth0.example.com')
.delete('/api/v2/client-grants/id1')
.reply(204)

const req = {
user: {
access_token: 'token'
}
};
return removeGrant(req).then(() => {
get.done();
del.done();
});
});
});
});
2 changes: 1 addition & 1 deletion webtask.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"title": "SSO Dashboard",
"name": "auth0-sso-dashboard",
"version": "2.4.0",
"version": "2.4.1",
"preVersion": "2.2.1",
"author": "Auth0",
"useHashName": false,
Expand Down

0 comments on commit a0fd0c6

Please sign in to comment.