Skip to content

Commit

Permalink
Add Gitea support and improve Git URL validation.
Browse files Browse the repository at this point in the history
This commit introduces support for Gitea in credential handling and Git operations. It also enhances Git URL validation by adding rules for `https://` formatting and issuing warnings for insecure credentials in URLs. Additionally, it ensures repository errors are reset in various Git actions for better reliability.
  • Loading branch information
SquirrelDevelopper committed Dec 24, 2024
1 parent 88239a6 commit 1a3439f
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 1a3439f

Please sign in to comment.