Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#9 gitlab #870

Merged
merged 10 commits into from
Feb 10, 2024
8 changes: 8 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,13 @@ GITHUB_ENTERPRISE_PORT=optional_if_enterprise_and_non_standard
GITHUB_ENTERPRISE_PROTOCOL=optional_if_enterprise_and_non_standard
GITHUB_SCOPE=public_repo



GITLAB_CLIENT_ID=01234567890123456789
GITLAB_CLIENT_SECRET=0123456789abcdef0123456789abcdef0123456
GITLAB_SCOPE=read_user read_repository write_repository profile read_api api
GITLAB_REDIRECT_URI=http://localhost:3000/api/oauth/return


NODE_ENV=development
SERVER_API_PROTOCOL=http
89 changes: 89 additions & 0 deletions td.server/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 td.server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
"resolutions": {},
"dependencies": {
"@babel/runtime": "^7.21.0",
"bitbucket": "^2.11.0",
"@gitbeaker/rest": "^39.34.2",
"axios": "^1.6.0",
"bitbucket": "^2.11.0",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"express-rate-limit": "^6.7.0",
Expand Down
3 changes: 3 additions & 0 deletions td.server/src/config/env.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import BitbucketEnv from '../env/Bitbucket.js';
import EncryptionEnv from '../env/Encryption.js';
import env from '../env/Env.js';
import GithubEnv from '../env/Github.js';
import GitlabEnv from "../env/Gitlab";
import ThreatDragonEnv from '../env/ThreatDragon.js';

const tryLoadDotEnv = () => {
const github = new GithubEnv();
const gitlab = new GitlabEnv();
const bitbucket = new BitbucketEnv();
const encryption = new EncryptionEnv();
const threatDragon = new ThreatDragonEnv();
env.get().addProvider(github);
env.get().addProvider(gitlab);
env.get().addProvider(encryption);
env.get().addProvider(bitbucket);
env.get().addProvider(threatDragon);
Expand Down
9 changes: 5 additions & 4 deletions td.server/src/controllers/configcontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ const logger = loggerHelper.get('controllers/configcontroller.js');
const config = (req, res) => responseWrapper.sendResponse(() => getConfig(), req, res, logger);

export const getConfig = () => ({
bitbucketEnabled: env.get().config.BITBUCKET_CLIENT_ID !== undefined && env.get().config.BITBUCKET_CLIENT_ID !== null,
githubEnabled: env.get().config.GITHUB_CLIENT_ID !== undefined && env.get().config.GITHUB_CLIENT_ID !== null,
localEnabled: true,
});
bitbucketEnabled: env.get().config.BITBUCKET_CLIENT_ID !== undefined && env.get().config.BITBUCKET_CLIENT_ID !== null,
githubEnabled: env.get().config.GITHUB_CLIENT_ID !== undefined && env.get().config.GITHUB_CLIENT_ID !== null,
gitlabEnabled: env.get().config.GITLAB_CLIENT_ID !== undefined && env.get().config.GITLAB_CLIENT_ID !== null,
localEnabled: true,
});

export default {
config
Expand Down
27 changes: 27 additions & 0 deletions td.server/src/env/Gitlab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Env } from './Env.js';

class GitlabEnv extends Env {
constructor () {
super('Gitlab');
}

get prefix () {
return 'GITLAB_';
}

get properties () {
return [
{ key: 'CLIENT_ID', required: false },
{ key: 'CLIENT_SECRET', required: false },
{ key: 'SCOPE', required: false },
{ key: 'ENTERPRISE_HOSTNAME', required: false },
{ key: 'ENTERPRISE_PROTOCOL', required: false },
{ key: 'ENTERPRISE_PORT', required: false },
{ key: 'USE_SEARCH', required: false },
{ key: 'SEARCH_QUERY', required: false },
{ key: 'REDIRECT_URI', required: false }
];
}
}

export default GitlabEnv;
101 changes: 101 additions & 0 deletions td.server/src/providers/gitlab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* @name gitlab
* @description Identity provider for Gitlab OAuth
*/
import axios from 'axios';

import env from '../env/Env.js';
import repositories from "../repositories";

const name = 'gitlab';

/**
* Determines if the GitHub provider is configured
* @returns {Boolean}
*/
const isConfigured = () => Boolean(env.get().config.GITLAB_CLIENT_ID);

/**
* Gets the Gitlab endpoint, which will be gitlab.com by default OR a custom endpoint for Gitlab enterprise scenarios
* @returns {String}
*/
const getGitlabUrl = () => {
const enterpriseHostname = env.get().config.GITLAB_ENTERPRISE_HOSTNAME;
if(enterpriseHostname) {
const port = env.get().config.GITLAB_ENTERPRISE_PORT || '';
const protocol = env.get().config.GITLAB_ENTERPRISE_PROTOCOL || 'https';
const enterpriseUrl = `${protocol}://${enterpriseHostname}${port ? ':' + port : ''}`;
return enterpriseUrl;
}
return 'https://gitlab.com';
};

/**
* Gets the Gitlab OAuth Login URL
* @returns {String}
*/
const getOauthRedirectUrl = () => {
const scope = env.get().config.GITLAB_SCOPE || 'read_user,read_repository,write_repository,profile';
return `${getGitlabUrl()}/oauth/authorize?scope=${scope}&redirect_uri=${env.get().config.GITLAB_REDIRECT_URI}&response_type=code&client_id=${env.get().config.GITLAB_CLIENT_ID}`;
};

/**
* Gets the return URL for our application, returning from gitlab
* @param {string} code
* @returns {String}
*/
const getOauthReturnUrl = (code) => {
let returnUrl = `/#/oauth-return?code=${code}`;
if (env.get().config.NODE_ENV === 'development') {
returnUrl = `http://localhost:8080${returnUrl}`;
}
return returnUrl;
};

/**
* Finishes the OAuth login, issues a JWT
* @param {String} code
* @returns {String} jwt
*/

const completeLoginAsync = async (code) => {
const url = `${getGitlabUrl()}/oauth/token`;
const body = {
client_id: env.get().config.GITLAB_CLIENT_ID,
client_secret: env.get().config.GITLAB_CLIENT_SECRET,
grant_type: 'authorization_code',
redirect_uri: env.get().config.GITLAB_REDIRECT_URI,
// grant_type
// code_verifier: 'CODE_VERIFIER',
code
};
const options = {
headers: {
accept: 'application/json'
}
};

const providerResp = await axios.post(url, body, options);


repositories.set("gitlabrepo");
const repo = repositories.get();
const fullUser = await repo.userAsync(providerResp.data.access_token);

const user = {
username: fullUser.username,
repos_url: fullUser.web_url
};
return {
user,
opts: providerResp.data
};
};

export default {
completeLoginAsync,
getOauthReturnUrl,
getOauthRedirectUrl,
isConfigured,
name
};
2 changes: 2 additions & 0 deletions td.server/src/providers/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import bitbucket from './bitbucket.js';
import github from './github.js';
import gitlab from "./gitlab";

/**
* An immutable object containing all
Expand All @@ -8,6 +9,7 @@ import github from './github.js';
*/
const all = Object.freeze({
github,
gitlab,
bitbucket
});

Expand Down
Loading