Skip to content

Commit 40df0d1

Browse files
authored
Merge branch 'main' into fix-additional-user-api-leaks
2 parents b91d5bf + 4956b73 commit 40df0d1

File tree

12 files changed

+181
-23
lines changed

12 files changed

+181
-23
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@finos/git-proxy",
3-
"version": "1.19.0",
3+
"version": "1.19.1",
44
"description": "Deploy custom push protections and policies on top of Git.",
55
"scripts": {
66
"cli": "node ./packages/git-proxy-cli/index.js",

src/db/file/pushes.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from 'fs';
22
import _ from 'lodash';
33
import Datastore from '@seald-io/nedb';
44
import { Action } from '../../proxy/actions/Action';
5-
import { toClass } from '../helper';
5+
import { toClass, trimTrailingDotGit } from '../helper';
66
import * as repo from './repo';
77
import { PushQuery } from '../types';
88

@@ -138,7 +138,7 @@ export const canUserCancelPush = async (id: string, user: string) => {
138138
return;
139139
}
140140

141-
const repoName = pushDetail.repoName.replace('.git', '');
141+
const repoName = trimTrailingDotGit(pushDetail.repoName);
142142
const isAllowed = await repo.isUserPushAllowed(repoName, user);
143143

144144
if (isAllowed) {
@@ -156,7 +156,8 @@ export const canUserApproveRejectPush = async (id: string, user: string) => {
156156
resolve(false);
157157
return;
158158
}
159-
const repoName = action.repoName.replace('.git', '');
159+
160+
const repoName = trimTrailingDotGit(action.repoName);
160161
const isAllowed = await repo.canUserApproveRejectPushRepo(repoName, user);
161162

162163
resolve(isAllowed);

src/db/helper.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,21 @@ export const toClass = function (obj: any, proto: any) {
33
obj.__proto__ = proto;
44
return obj;
55
};
6+
7+
export const trimTrailingDotGit = (str: string): string => {
8+
const target = '.git';
9+
if (str.endsWith(target)) {
10+
// extract string from 0 to the end minus the length of target
11+
return str.slice(0, -target.length);
12+
}
13+
return str;
14+
};
15+
16+
export const trimPrefixRefsHeads = (str: string): string => {
17+
const target = 'refs/heads/';
18+
if (str.startsWith(target)) {
19+
// extract string from the end of the target to the end of str
20+
return str.slice(target.length);
21+
}
22+
return str;
23+
};

src/db/mongo/pushes.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { connect, findDocuments, findOneDocument } from './helper';
22
import { Action } from '../../proxy/actions';
3-
import { toClass } from '../helper';
3+
import { toClass, trimTrailingDotGit } from '../helper';
44
import * as repo from './repo';
55
import { Push, PushQuery } from '../types';
66

@@ -108,7 +108,7 @@ export const canUserApproveRejectPush = async (id: string, user: string) => {
108108
return;
109109
}
110110

111-
const repoName = action.repoName.replace('.git', '');
111+
const repoName = trimTrailingDotGit(action.repoName);
112112
const isAllowed = await repo.canUserApproveRejectPushRepo(repoName, user);
113113

114114
resolve(isAllowed);
@@ -123,7 +123,7 @@ export const canUserCancelPush = async (id: string, user: string) => {
123123
return;
124124
}
125125

126-
const repoName = pushDetail.repoName.replace('.git', '');
126+
const repoName = trimTrailingDotGit(pushDetail.repoName);
127127
const isAllowed = await repo.isUserPushAllowed(repoName, user);
128128

129129
if (isAllowed) {

src/proxy/processors/push-action/checkRepoInAuthorisedList.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Action, Step } from '../../actions';
22
import { getRepos } from '../../../db';
33
import { Repo } from '../../../db/types';
4+
import { trimTrailingDotGit } from '../../../db/helper';
45

56
// Execute if the repo is approved
67
const exec = async (
@@ -14,8 +15,8 @@ const exec = async (
1415
console.log(list);
1516

1617
const found = list.find((x: Repo) => {
17-
const targetName = action.repo.replace('.git', '').toLowerCase();
18-
const allowedName = `${x.project}/${x.name}`.replace('.git', '').toLowerCase();
18+
const targetName = trimTrailingDotGit(action.repo.toLowerCase());
19+
const allowedName = trimTrailingDotGit(`${x.project}/${x.name}`.toLowerCase());
1920
console.log(`${targetName} = ${allowedName}`);
2021
return targetName === allowedName;
2122
});

src/proxy/processors/push-action/checkUserPushPermission.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import { Action, Step } from '../../actions';
22
import { getUsers, isUserPushAllowed } from '../../../db';
3+
import { trimTrailingDotGit } from '../../../db/helper';
34

45
// Execute if the repo is approved
56
const exec = async (req: any, action: Action): Promise<Action> => {
67
const step = new Step('checkUserPushPermission');
78

8-
const repoName = action.repo.split('/')[1].replace('.git', '');
9+
const repoSplit = trimTrailingDotGit(action.repo.toLowerCase()).split('/');
10+
// we expect there to be exactly one / separating org/repoName
11+
if (repoSplit.length != 2) {
12+
step.setError('Server-side issue extracting repoName');
13+
action.addStep(step);
14+
return action;
15+
}
16+
// pull the 2nd value of the split for repoName
17+
const repoName = repoSplit[1];
918
let isUserAllowed = false;
1019
let user = action.user;
1120

src/ui/views/OpenPushRequests/components/PushesTable.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { KeyboardArrowRight } from '@material-ui/icons';
1616
import Search from '../../../components/Search/Search';
1717
import Pagination from '../../../components/Pagination/Pagination';
1818
import { PushData } from '../../../../types/models';
19+
import { trimPrefixRefsHeads, trimTrailingDotGit } from '../../../../db/helper';
1920

2021
interface PushesTableProps {
2122
[key: string]: any;
@@ -100,8 +101,8 @@ const PushesTable: React.FC<PushesTableProps> = (props) => {
100101
</TableHead>
101102
<TableBody>
102103
{[...currentItems].reverse().map((row) => {
103-
const repoFullName = row.repo.replace('.git', '');
104-
const repoBranch = row.branch.replace('refs/heads/', '');
104+
const repoFullName = trimTrailingDotGit(row.repo);
105+
const repoBranch = trimPrefixRefsHeads(row.branch);
105106
const commitTimestamp =
106107
row.commitData[0]?.commitTs || row.commitData[0]?.commitTimestamp;
107108

src/ui/views/PushDetails/PushDetails.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { CheckCircle, Visibility, Cancel, Block } from '@material-ui/icons';
2323
import Snackbar from '@material-ui/core/Snackbar';
2424
import Tooltip from '@material-ui/core/Tooltip';
2525
import { PushData } from '../../../types/models';
26+
import { trimPrefixRefsHeads, trimTrailingDotGit } from '../../../db/helper';
2627

2728
const Dashboard: React.FC = () => {
2829
const { id } = useParams<{ id: string }>();
@@ -105,8 +106,8 @@ const Dashboard: React.FC = () => {
105106
};
106107
}
107108

108-
const repoFullName = data.repo.replace('.git', '');
109-
const repoBranch = data.branch.replace('refs/heads/', '');
109+
const repoFullName = trimTrailingDotGit(data.repo);
110+
const repoBranch = trimPrefixRefsHeads(data.branch);
110111

111112
const generateIcon = (title: string) => {
112113
switch (title) {

src/ui/views/RepoDetails/RepoDetails.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { useNavigate, useParams } from 'react-router-dom';
2020
import { UserContext } from '../../../context';
2121
import CodeActionButton from '../../components/CustomButtons/CodeActionButton';
2222
import { Box } from '@material-ui/core';
23+
import { trimTrailingDotGit } from '../../../db/helper';
2324

2425
interface RepoData {
2526
project: string;
@@ -148,7 +149,7 @@ const RepoDetails: React.FC = () => {
148149
<FormLabel component='legend'>URL</FormLabel>
149150
<h4>
150151
<a href={data.url} target='_blank' rel='noopener noreferrer'>
151-
{data.url.replace('.git', '')}
152+
{trimTrailingDotGit(data.url)}
152153
</a>
153154
</h4>
154155
</GridItem>

0 commit comments

Comments
 (0)