Skip to content

Commit

Permalink
Merge pull request #599 from SquirrelCorporation/feat-support-gitea
Browse files Browse the repository at this point in the history
[FEAT] Add Gitea support and improve Git URL validation.
  • Loading branch information
SquirrelDeveloper authored Dec 24, 2024
2 parents fe10903 + 1a3439f commit f986444
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ProFormSelect,
ProFormText,
} from '@ant-design/pro-components';
import { message } from 'antd';
import React from 'react';
import { API, SsmGit } from 'ssm-shared-lib';

Expand Down Expand Up @@ -68,7 +69,23 @@ const GitForm: React.FC<GitFormProps> = ({ selectedRecord, repositories }) => (
name={'remoteUrl'}
label={'Remote Url'}
initialValue={selectedRecord?.remoteUrl}
rules={[{ required: true }]}
rules={[
{ required: true },
{ type: 'url' },
{ pattern: /https:\/\//, message: 'Please include https://' },
]}
fieldProps={{
onBlur: (e) => {
const value = e.target.value;
const regex = /https?:\/\/[^@\n]+:[^@\n]+@/; // Matches user:password@ in URLs
if (regex.test(value)) {
void message.warning({
content:
'Remote URL contains a username or access token. Consider removing it for security.',
});
}
},
}}
/>
<ProFormText
width={'md'}
Expand Down
43 changes: 30 additions & 13 deletions server/src/helpers/git/credential.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { GitProcess } from 'dugite';
import { trim } from 'lodash';
import { SsmGit } from 'ssm-shared-lib';
import logger from '../../logger';
import { getRemoteUrl } from './inspect';

// TODO: support folderLocation as rawUrl like `/Users/linonetwo/Desktop/repo/playbooks-repository-sync-js/test/mockUpstreamRepo/credential` for test, or gitlab url.
Expand Down Expand Up @@ -47,6 +48,18 @@ export const getAzureReposUrlWithCredential = (
.replace('https://dev.azure.com/', `https://${username}:${accessToken}@dev.azure.com/`),
);

export const getGiteaUrlWithCredential = (
rawUrl: string,
username: string,
accessToken: string,
): string =>
trim(
rawUrl.replaceAll('\n', '').replace(
/https?:\/\/([a-zA-Z0-9.-]+(:\d+)?)(\/.*)/, // Matches domain, optional port, and trailing path
`https://${username}:${accessToken}@$1$3`, // Replaces with credentials and preserves the rest of the path
),
);

const getUrlWithOutCredential = (urlWithCredential: string): string =>
trim(urlWithCredential.replace(/.+@/, 'https://'));

Expand All @@ -58,6 +71,7 @@ const getUrlWithOutCredential = (urlWithCredential: string): string =>
* @param accessToken
* @param remoteName
* @param serviceType
* @param domain
*/
export async function credentialOn(
directory: string,
Expand Down Expand Up @@ -85,7 +99,15 @@ export async function credentialOn(
gitUrlWithCredential = getAzureReposUrlWithCredential(remoteUrl, userName, accessToken);
break;
}
case SsmGit.Services.Gitea: {
gitUrlWithCredential = getGiteaUrlWithCredential(remoteUrl, userName, accessToken);
break;
}
default: {
throw new Error(`Unknown service type ${serviceType}`);
}
}
logger.error(gitUrlWithCredential);
await GitProcess.exec(['remote', 'add', remoteName, gitUrlWithCredential], directory);
await GitProcess.exec(['remote', 'set-url', remoteName, gitUrlWithCredential], directory);
}
Expand All @@ -103,23 +125,18 @@ export async function credentialOff(
serviceType = SsmGit.Services.Github,
): Promise<void> {
const gitRepoUrl = remoteUrl ?? (await getRemoteUrl(directory, remoteName));
let gitUrlWithOutCredential;
let gitUrlWithOutCredential: string;
switch (serviceType) {
case SsmGit.Services.Github: {
case SsmGit.Services.Github:
case SsmGit.Services.GitLab:
case SsmGit.Services.Bitbucket:
case SsmGit.Services.AzureRepos:
case SsmGit.Services.Gitea: {
gitUrlWithOutCredential = getUrlWithOutCredential(gitRepoUrl);
break;
}
case SsmGit.Services.GitLab: {
gitUrlWithOutCredential = getUrlWithOutCredential(gitRepoUrl);
break;
}
case SsmGit.Services.Bitbucket: {
gitUrlWithOutCredential = getUrlWithOutCredential(gitRepoUrl);
break;
}
case SsmGit.Services.AzureRepos: {
gitUrlWithOutCredential = getUrlWithOutCredential(gitRepoUrl);
break;
default: {
throw new Error(`Unknown service type ${serviceType}`);
}
}
await GitProcess.exec(['remote', 'set-url', remoteName, gitUrlWithOutCredential], directory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class GitPlaybooksRepositoryComponent
async clone(syncAfter = false) {
this.childLogger.info('Clone starting...');
try {
await GitPlaybooksRepositoryUseCases.resetRepositoryError(this.uuid);
try {
void Shell.FileSystemManager.createDirectory(this.directory, DIRECTORY_ROOT);
} catch (error: any) {
Expand Down Expand Up @@ -101,6 +102,7 @@ class GitPlaybooksRepositoryComponent

async commitAndSync() {
try {
await GitPlaybooksRepositoryUseCases.resetRepositoryError(this.uuid);
await commitAndSync({
...this.options,
logger: {
Expand Down Expand Up @@ -134,6 +136,7 @@ class GitPlaybooksRepositoryComponent

async forcePull() {
try {
await GitPlaybooksRepositoryUseCases.resetRepositoryError(this.uuid);
await forcePull({
...this.options,
logger: {
Expand Down
3 changes: 2 additions & 1 deletion shared-lib/src/enums/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export enum Services {
Github = 'github',
GitLab = 'gitlab',
Bitbucket = 'bitbucket',
AzureRepos = 'azure-repos'
AzureRepos = 'azure-repos',
Gitea = 'gitea'
}

0 comments on commit f986444

Please sign in to comment.