Skip to content

Commit 70fad8e

Browse files
authored
Merge pull request #800 from steve-winter/#1-Bitbucket
Resolves issue #1 - Enables Bitbucket Auth and Repo
2 parents e8eb7bc + d2f4dd3 commit 70fad8e

40 files changed

+1135
-399
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@
4444

4545
# Express server
4646
!td.server
47+
!td.server/src/**/*.js
48+
!td.server/test/**/*.js
4749
!td.server/**/*.js
50+
!td.server/**/**/*.js
4851
!td.server/.babelrc
4952
!td.server/README.md
5053
!td.server/package.json
@@ -61,7 +64,6 @@
6164
!td.vue/src/assets/*.jpg
6265
!td.vue/src/assets/*.svg
6366
!td.vue/src/components/
64-
!td.vue/src/components/
6567
!td.vue/src/components/printed-report/
6668
!td.vue/src/components/report/
6769
!td.vue/src/desktop/

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Mike Goodwin's [original](https://github.com/mike-goodwin/owasp-threat-dragon)
4747
which has the issues and pull requests from October 2015 up to June 2020.
4848

4949
Threat Dragon is [primarily a web application](https://github.com/OWASP/threat-dragon/releases),
50-
with threat model files stored in GitHub. Over time other storage methods will become available.
50+
with threat model files stored in GitHub or Bitbucket. Over time other storage methods will become available.
5151

5252
There are [desktop versions](https://github.com/OWASP/threat-dragon/releases) of Threat Dragon
5353
which store the threat model files on the local filesystem rather than in a repository.
@@ -83,8 +83,8 @@ The web application variant of Threat Dragon requires some environment variables
8383
follow [the documentation](https://owasp.org/www-project-threat-dragon/docs-2/install-environment/)
8484
on how to set these variables.
8585

86-
The Threat Dragon web application uses GitHub to store threat models,
87-
so you need to go to your GitHub account and register it as a GitHub application.
86+
The Threat Dragon web application uses GitHub or Bitbucket to store threat models,
87+
so you need to go to your GitHub or Bitbucket account and register it as a GitHub application.
8888
There is a [step by step guide](https://owasp.org/www-project-threat-dragon/docs-2/install-environment/)
8989
on how to do this. Github Enterprise is also supported.
9090

example.env

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,10 @@ SERVER_API_PROTOCOL=http
1111
ENCRYPTION_KEYS='[{"isPrimary": true, "id": 0, "value": "11223344556677889900aabbccddeeff"}]'
1212
ENCRYPTION_JWT_SIGNING_KEY=asdfasdfasdf
1313
ENCRYPTION_JWT_REFRESH_SIGNING_KEY=fljasdlfkjadf
14+
15+
16+
17+
BITBUCKET_WORKSPACE=workspace_name
18+
BITBUCKET_CLIENT_ID=01234567890123456789
19+
BITBUCKET_CLIENT_SECRET=0123456789abcdef0123456789abcdef0123456
20+
BITBUCKET_SCOPE=repository:write

td.server/package-lock.json

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

td.server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"resolutions": {},
3737
"dependencies": {
3838
"@babel/runtime": "^7.21.0",
39+
"bitbucket": "^2.11.0",
3940
"axios": "^1.6.0",
4041
"dotenv": "^16.0.3",
4142
"express": "^4.18.2",
@@ -69,7 +70,6 @@
6970
"sinon-chai": "^3.7.0",
7071
"supertest": "^4.0.2"
7172
},
72-
7373
"overrides": {
7474
"@achrinza/node-ipc": ">=10.1.10",
7575
"@babel/traverse": ">=7.23.2",

td.server/src/config/env.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1+
import BitbucketEnv from '../env/Bitbucket.js';
12
import EncryptionEnv from '../env/Encryption.js';
23
import env from '../env/Env.js';
34
import GithubEnv from '../env/Github.js';
45
import ThreatDragonEnv from '../env/ThreatDragon.js';
56

67
const tryLoadDotEnv = () => {
78
const github = new GithubEnv();
9+
const bitbucket = new BitbucketEnv();
810
const encryption = new EncryptionEnv();
911
const threatDragon = new ThreatDragonEnv();
1012
env.get().addProvider(github);
1113
env.get().addProvider(encryption);
14+
env.get().addProvider(bitbucket);
1215
env.get().addProvider(threatDragon);
1316
env.get().hydrate();
1417
};

td.server/src/controllers/threatmodelcontroller.js

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import env from '../env/Env.js';
22
import loggerHelper from '../helpers/logger.helper.js';
3-
import repository from '../repositories/threatmodelrepository.js';
3+
import repositories from "../repositories";
44
import responseWrapper from './responseWrapper.js';
55
import { serverError } from './errors.js';
66

77
const logger = loggerHelper.get('controllers/threatmodelcontroller.js');
88

99
const repos = (req, res) => responseWrapper.sendResponseAsync(async () => {
10+
const repository = repositories.get();
11+
1012
const page = req.query.page || 1;
1113
let reposResp;
1214
let repos;
@@ -21,15 +23,23 @@ const repos = (req, res) => responseWrapper.sendResponseAsync(async () => {
2123
repos = reposResp[0];
2224
}
2325
const headers = reposResp[1];
26+
const pageLinks = reposResp[2];
2427
logger.debug('API repos request: ' + req);
2528

29+
const pagination = getPagination(headers, pageLinks, page);
30+
2631
return {
2732
repos: repos.map((x) => x.full_name),
28-
pagination: getPagination(headers, page)
33+
pagination: pagination
2934
};
3035
}, req, res, logger);
3136

37+
38+
3239
const branches = (req, res) => responseWrapper.sendResponseAsync(async () => {
40+
41+
const repository = repositories.get();
42+
3343
const repoInfo = {
3444
organisation: req.params.organisation,
3545
repo: req.params.repo,
@@ -40,15 +50,21 @@ const branches = (req, res) => responseWrapper.sendResponseAsync(async () => {
4050
const branchesResp = await repository.branchesAsync(repoInfo, req.provider.access_token);
4151
const branches = branchesResp[0];
4252
const headers = branchesResp[1];
53+
const pageLinks = branchesResp[2];
54+
4355
const branchNames = branches.map((x) => x.name);
4456

57+
const pagination = getPagination(headers, pageLinks, repoInfo.page);
58+
4559
return {
4660
branches: branchNames,
47-
pagination: getPagination(headers, repoInfo.page)
61+
pagination: pagination
4862
};
4963
}, req, res, logger);
5064

5165
const models = (req, res) => responseWrapper.sendResponseAsync(async () => {
66+
const repository = repositories.get();
67+
5268
const branchInfo = {
5369
organisation: req.params.organisation,
5470
repo: req.params.repo,
@@ -70,6 +86,7 @@ const models = (req, res) => responseWrapper.sendResponseAsync(async () => {
7086
}, req, res, logger);
7187

7288
const model = (req, res) => responseWrapper.sendResponseAsync(async () => {
89+
const repository = repositories.get();
7390
const modelInfo = {
7491
organisation: req.params.organisation,
7592
repo: req.params.repo,
@@ -83,6 +100,8 @@ const model = (req, res) => responseWrapper.sendResponseAsync(async () => {
83100
}, req, res, logger);
84101

85102
const create = async (req, res) => {
103+
const repository = repositories.get();
104+
86105
const modelBody = {
87106
organisation: req.params.organisation,
88107
repo: req.params.repo,
@@ -102,6 +121,8 @@ const create = async (req, res) => {
102121
};
103122

104123
const update = async (req, res) => {
124+
const repository = repositories.get();
125+
105126
const modelBody = {
106127
organisation: req.params.organisation,
107128
repo: req.params.repo,
@@ -121,6 +142,8 @@ const update = async (req, res) => {
121142
};
122143

123144
const deleteModel = async (req, res) => {
145+
const repository = repositories.get();
146+
124147
const modelInfo = {
125148
organisation: req.params.organisation,
126149
repo: req.params.repo,
@@ -138,10 +161,28 @@ const deleteModel = async (req, res) => {
138161
}
139162
};
140163

141-
const getPagination = (headers, page) => {
142-
const pagination = { page, next: false, prev: false };
143-
const linkHeader = headers.link;
164+
const getPagination = (headers, pageLinks, page) => {
165+
166+
if(headers === undefined || headers === null || (Object.keys(headers).length === 0) || headers?.link === null){
167+
if (pageLinks === undefined || pageLinks === null || (Object.keys(pageLinks).length === 0)) {
168+
return {page, next: false, prev: false};
169+
}
170+
return getPaginationFromPageLinks(pageLinks, page);
171+
}
172+
return getPaginationFromHeaders(headers, page);
173+
174+
};
144175

176+
const getPaginationFromPageLinks = (pageLinks, page) => {
177+
const pagination = {page, next: false, prev: false};
178+
pagination.next = pageLinks.next;
179+
pagination.prev = pageLinks.prev;
180+
return pagination;
181+
};
182+
183+
const getPaginationFromHeaders = (headers, page) => {
184+
const pagination = {page, next: false, prev: false};
185+
const linkHeader = headers.link;
145186
if (linkHeader) {
146187
linkHeader.split(',').forEach((link) => {
147188
const isLinkType = (type) => link.split(';')[1].split('=')[1] === type;
@@ -155,7 +196,6 @@ const getPagination = (headers, page) => {
155196
}
156197
});
157198
}
158-
159199
return pagination;
160200
};
161201

td.server/src/env/Bitbucket.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Env } from './Env.js';
2+
3+
class BitbucketEnv extends Env {
4+
constructor () {
5+
super('Bitbucket');
6+
}
7+
8+
get prefix () {
9+
return 'BITBUCKET_';
10+
}
11+
12+
get properties () {
13+
return [
14+
{ key: 'CLIENT_ID', required: false },
15+
{ key: 'CLIENT_SECRET', required: false },
16+
{ key: 'SCOPE', required: false },
17+
{ key: 'ENTERPRISE_HOSTNAME', required: false },
18+
{ key: 'ENTERPRISE_PROTOCOL', required: false },
19+
{ key: 'ENTERPRISE_PORT', required: false },
20+
{ key: 'USE_SEARCH', required: false },
21+
{ key: 'SEARCH_QUERY', required: false },
22+
{ key: 'WORKSPACE', required: false }
23+
];
24+
}
25+
}
26+
27+
export default BitbucketEnv;

td.server/src/env/Github.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ class GithubEnv extends Env {
1111

1212
get properties () {
1313
return [
14-
{ key: 'CLIENT_ID', required: true },
15-
{ key: 'CLIENT_SECRET', required: true },
14+
{ key: 'CLIENT_ID', required: false },
15+
{ key: 'CLIENT_SECRET', required: false },
1616
{ key: 'SCOPE', required: false },
1717
{ key: 'ENTERPRISE_HOSTNAME', required: false },
1818
{ key: 'ENTERPRISE_PROTOCOL', required: false },

0 commit comments

Comments
 (0)