Skip to content

Commit

Permalink
Merge pull request #749 from 06kellyjac/allow_custom_proxy_domain
Browse files Browse the repository at this point in the history
feat: allow for providing an alternative domain for the proxy
  • Loading branch information
JamieSlome authored Oct 31, 2024
2 parents 00a9d12 + 0174814 commit a91570e
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 68 deletions.
1 change: 0 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
VITE_API_URI=http://localhost:8080
VITE_SERVER_URI=http://localhost:8000
4 changes: 4 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"description": "Customisable questions to add to attestation form",
"type": "object"
},
"domains": {
"description": "Provide domains to use alternative to the defaults",
"type": "object"
},
"privateOrganizations": {
"description": "Pattern searches for listed private organizations are disabled",
"type": "array"
Expand Down
55 changes: 55 additions & 0 deletions cypress/e2e/repo.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
describe('Repo', () => {
beforeEach(() => {
cy.visit('/admin/repo');

// prevent failures on 404 request and uncaught promises
cy.on('uncaught:exception', () => false);
});

describe('Code button for repo row', () => {
it('Opens tooltip with correct content and can copy', () => {
const cloneURL = 'http://localhost:8000/finos/test-repo.git';
const tooltipQuery = 'div[role="tooltip"]';

cy
// tooltip isn't open to start with
.get(tooltipQuery)
.should('not.exist');

cy
// find the entry for finos/test-repo
.get('a[href="/admin/repo/test-repo"]')
// take it's parent row
.closest('tr')
// find the nearby span containing Code we can click to open the tooltip
.find('span')
.contains('Code')
.should('exist')
.click();

cy
// find the newly opened tooltip
.get(tooltipQuery)
.should('exist')
.find('span')
// check it contains the url we expect
.contains(cloneURL)
.should('exist')
.parent()
// find the adjacent span that contains the svg
.find('span')
.next()
// check it has the copy icon first and click it
.get('svg.octicon-copy')
.should('exist')
.click()
// check the icon has changed to the check icon
.get('svg.octicon-copy')
.should('not.exist')
.get('svg.octicon-check')
.should('exist');

// failed to successfully check the clipboard
});
});
});
14 changes: 13 additions & 1 deletion cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,16 @@
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

// start of a login command with sessions
// TODO: resolve issues with the CSRF token
Cypress.Commands.add('login', (username, password) => {
cy.session([username, password], () => {
cy.visit('/login');
cy.get('[data-test=username]').type(username);
cy.get('[data-test=password]').type(password);
cy.get('[data-test=login]').click();
cy.url().should('contain', '/admin/profile');
});
});
1 change: 1 addition & 0 deletions proxy.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
}
]
},
"domains": {},
"privateOrganizations": [],
"urlShortener": "",
"contactEmail": "",
Expand Down
1 change: 1 addition & 0 deletions scripts/doc-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ try {
console.log(genDocOutput);

const schemaDoc = readFileSync(`${tempdir}${sep}schema.md`, 'utf-8')
.replace(/\s\s\n\n<\/summary>/g, '\n</summary>')
.replace(/# GitProxy configuration file/g, '# Schema Reference'); // https://github.com/finos/git-proxy/pull/327#discussion_r1377343213
const docString = `---
title: Schema Reference
Expand Down
9 changes: 9 additions & 0 deletions src/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ let _privateOrganizations = defaultSettings.privateOrganizations;
let _urlShortener = defaultSettings.urlShortener;
let _contactEmail = defaultSettings.contactEmail;
let _csrfProtection = defaultSettings.csrfProtection;
let _domains = defaultSettings.domains;

// Get configured proxy URL
const getProxyUrl = () => {
Expand Down Expand Up @@ -189,6 +190,13 @@ const getSSLCertPath = () => {
return _sslCertPath;
};

const getDomains = () => {
if (_userSettings && _userSettings.domains) {
_domains = _userSettings.domains;
}
return _domains;
};

exports.getAPIs = getAPIs;
exports.getProxyUrl = getProxyUrl;
exports.getAuthorisedList = getAuthorisedList;
Expand All @@ -207,3 +215,4 @@ exports.getCSRFProtection = getCSRFProtection;
exports.getPlugins = getPlugins;
exports.getSSLKeyPath = getSSLKeyPath;
exports.getSSLCertPath = getSSLCertPath;
exports.getDomains = getDomains;
13 changes: 13 additions & 0 deletions src/service/proxyURL.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { GIT_PROXY_SERVER_PORT: PROXY_HTTP_PORT, GIT_PROXY_UI_PORT: UI_PORT } =
require('../config/env').Vars;
const config = require('../config');

module.exports = {
getProxyURL: (req) => {
const defaultURL = `${req.protocol}://${req.headers.host}`.replace(
`:${UI_PORT}`,
`:${PROXY_HTTP_PORT}`,
);
return config.getDomains().proxy ?? defaultURL;
},
};
9 changes: 7 additions & 2 deletions src/service/routes/repo.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const express = require('express');
const router = new express.Router();
const db = require('../../db');
const { getProxyURL } = require('../proxyURL');

router.get('/', async (req, res) => {
const proxyURL = getProxyURL(req);
const query = {
type: 'push',
};
Expand All @@ -18,12 +20,15 @@ router.get('/', async (req, res) => {
query[k] = v;
}

res.send(await db.getRepos(query));
const qd = await db.getRepos(query);
res.send(qd.map((d) => ({ ...d, proxyURL })));
});

router.get('/:name', async (req, res) => {
const proxyURL = getProxyURL(req);
const name = req.params.name;
res.send(await db.getRepo(name));
const qd = await db.getRepo(name);
res.send({ ...qd, proxyURL });
});

router.patch('/:name/user/push', async (req, res) => {
Expand Down
4 changes: 2 additions & 2 deletions src/ui/views/RepoDetails/RepoDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ export default function RepoDetails() {
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Something went wrong ...</div>;

const { project: org, name } = data || {};
const cloneURL = `${import.meta.env.VITE_SERVER_URI}/${org}/${name}.git`;
const { project: org, name, proxyURL } = data || {};
const cloneURL = `${proxyURL}/${org}/${name}.git`;

return (
<GridContainer>
Expand Down
4 changes: 2 additions & 2 deletions src/ui/views/RepoList/Components/RepoOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,8 @@ export default function Repositories(props) {
});
};

const { project: org, name } = props?.data || {};
const cloneURL = `${window.location.origin.toString()}/${org}/${name}.git`;
const { project: org, name, proxyURL } = props?.data || {};
const cloneURL = `${proxyURL}/${org}/${name}.git`;

return (
<TableRow>
Expand Down
51 changes: 51 additions & 0 deletions test/proxyURL.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const chai = require('chai');
const sinon = require('sinon');
const express = require('express');
const chaiHttp = require('chai-http');
const { getProxyURL } = require('../src/service/proxyURL');
const config = require('../src/config');

chai.use(chaiHttp);
chai.should();
const expect = chai.expect;

const genSimpleServer = () => {
const app = express();
app.get('/', (req, res) => {
res.contentType('text/html');
res.send(getProxyURL(req));
});
return app;
};

describe('proxyURL', async () => {
afterEach(() => {
sinon.restore();
});

it('pulls the request path with no override', async () => {
const app = genSimpleServer();
const res = await chai.request(app).get('/').send();
res.should.have.status(200);

// request url without trailing slash
const reqURL = res.request.url.slice(0, -1);
expect(res.text).to.equal(reqURL);
expect(res.text).to.match(/https?:\/\/127.0.0.1:\d+/);
});

it('can override providing a proxy value', async () => {
const proxyURL = 'https://amazing-proxy.path.local';
// stub getDomains
const configGetDomainsStub = sinon.stub(config, 'getDomains').returns({ proxy: proxyURL });

const app = genSimpleServer();
const res = await chai.request(app).get('/').send();
res.should.have.status(200);

// the stub worked
expect(configGetDomainsStub.calledOnce).to.be.true;

expect(res.text).to.equal(proxyURL);
});
});
Loading

0 comments on commit a91570e

Please sign in to comment.