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

Gitea support #8131

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
nits
  • Loading branch information
anbraten committed Mar 5, 2022
commit 3ff0f29a09a8a7b3827c470900bc35b32bfb4e43
2 changes: 1 addition & 1 deletion components/dashboard/src/settings/Integrations.tsx
Original file line number Diff line number Diff line change
@@ -648,7 +648,7 @@ export function GitIntegrationModal(props: ({
<AlertBox>You need to activate this integration.</AlertBox>
)}
<div className="flex flex-col">
<span className="text-gray-500">{props.headerText || "Configure a Git integration with a GitLab or GitHub self-hosted instance."}</span>
<span className="text-gray-500">{props.headerText || "Configure a Git integration with a GitLab, GitHub or Gitea self-hosted instance."}</span>
</div>

<div className="overscroll-contain max-h-96 overflow-y-auto pr-2">
6 changes: 3 additions & 3 deletions components/server/ee/src/prebuilds/gitea-app.ts
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ export class GiteaApp {
interface GiteaPushHook {
}

interface GiteaRepository {
}
// interface GiteaRepository {
// }

interface GiteaProject {}
// interface GiteaProject {}
9 changes: 8 additions & 1 deletion components/server/src/auth/auth-provider-service.ts
Original file line number Diff line number Diff line change
@@ -108,7 +108,14 @@ export class AuthProviderService {
}
protected initializeNewProvider(newEntry: AuthProviderEntry.NewEntry): AuthProviderEntry {
const { host, type, clientId, clientSecret } = newEntry;
const urls = type === "GitHub" ? githubUrls(host) : (type === "GitLab" ? gitlabUrls(host) : (type === "Gitea" ? giteaUrls(host) : undefined));
let urls: { authorizationUrl: string, tokenUrl: string } | undefined = undefined;
if (type === "GitHub") {
urls =githubUrls(host);
} else if (type === "GitLab") {
urls =gitlabUrls(host);
} else if (type === "Gitea") {
urls = giteaUrls(host);
}
if (!urls) {
throw new Error("Unexpected service type.");
}
6 changes: 2 additions & 4 deletions components/server/src/gitea/api.ts
Original file line number Diff line number Diff line change
@@ -20,12 +20,12 @@ export namespace Gitea {
constructor(msg?: string, httpError?: any) {
super(msg);
this.httpError = httpError;
this.name = 'GitLabApiError';
this.name = 'GiteaApiError';
}
}
export namespace ApiError {
export function is(something: any): something is ApiError {
return !!something && something.name === 'GitLabApiError';
return !!something && something.name === 'GiteaApiError';
}
export function isNotFound(error: ApiError): boolean {
return !!error.httpError?.description.startsWith("404");
@@ -70,8 +70,6 @@ export class GiteaRestApi {
oauthToken = giteaToken.value;
}
const api = Gitea.create(this.config.host, oauthToken);
const repo = api.repos.repoGet('anbraten', 'gitea-js');
console.log(repo);
return api;
}

2 changes: 1 addition & 1 deletion components/server/src/gitea/gitea-auth-provider.ts
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@
currentScopes: this.readScopesFromVerifyParams(tokenResponse)
}
} catch (error) {
// TODO: cleanup
// TODO: cleanup & check for Gitea instead of Gitlab
// if (error && typeof error.description === "string" && error.description.includes("403 Forbidden")) {
// // If Gitlab is configured to disallow OAuth-token based API access for unconfirmed users, we need to reject this attempt
// // 403 Forbidden - You (@...) must accept the Terms of Service in order to perform this action. Please access GitLab from a web browser to accept these terms.
14 changes: 4 additions & 10 deletions components/server/src/gitea/gitea-context-parser.ts
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ import { convertRepo } from './convert';
}

public async handle(ctx: TraceContext, user: User, contextUrl: string): Promise<CommitContext> {
const span = TraceContext.startSpan("GitlabContextParser", ctx);
const span = TraceContext.startSpan("GiteaContextParser", ctx);
span.setTag("contextUrl", contextUrl);

try {
@@ -69,7 +69,6 @@ import { convertRepo } from './convert';
}
}

// https://gitlab.com/AlexTugarev/gp-test
protected async handleDefaultContext(user: User, host: string, owner: string, repoName: string): Promise<NavigatorContext> {
try {
const repository = await this.fetchRepo(user, owner, repoName);
@@ -116,9 +115,6 @@ import { convertRepo } from './convert';
}
}

// https://gitlab.com/AlexTugarev/gp-test/tree/wip
// https://gitlab.com/AlexTugarev/gp-test/tree/wip/folder
// https://gitlab.com/AlexTugarev/gp-test/blob/wip/folder/empty.file.jpeg
protected async handleTreeContext(user: User, host: string, owner: string, repoName: string, segments: string[]): Promise<NavigatorContext> {

try {
@@ -201,11 +197,12 @@ import { convertRepo } from './convert';
const possibleTag = await this.giteaApi.run<Gitea.Tag>(user, async g => {
return g.repos.repoGetTag(owner, repoName, candidate);
});
// TODO
// If the tag does not exist, the GitLab API returns with NotFound or InternalServerError.
const isNotFoundTag = Gitea.ApiError.is(possibleTag) && (Gitea.ApiError.isNotFound(possibleTag) || Gitea.ApiError.isInternalServerError(possibleTag));
if (!isNotFoundTag) {
if (Gitea.ApiError.is(possibleTag)) {
throw new Error(`GitLab ApiError on searching for possible tags for ${owner}/${repoName}/tree/${segments.join('/')}: ${possibleTag}`);
throw new Error(`Gitea ApiError on searching for possible tags for ${owner}/${repoName}/tree/${segments.join('/')}: ${possibleTag}`);
}

if (!possibleTag.commit?.sha || !possibleTag.name) {
@@ -231,7 +228,6 @@ import { convertRepo } from './convert';
return { ...branchOrTagObject, fullPath };
}

// https://gitlab.com/AlexTugarev/gp-test/merge_requests/1
protected async handlePullRequestContext(user: User, host: string, owner: string, repoName: string, nr: number): Promise<PullRequestContext> {
const result = await this.giteaApi.run<Gitea.PullRequest>(user, async g => {
return g.repos.repoGetPullRequest(owner, repoName, nr);
@@ -307,7 +303,7 @@ import { convertRepo } from './convert';
return g.repos.repoGetSingleCommit(owner, repoName, sha);
});
if (Gitea.ApiError.is(result)) {
if (result.message === 'GitLab responded with code 404') {
if (result.message === 'Gitea responded with code 404') {
throw new Error(`Couldn't find commit #${sha} in repository ${owner}/${repoName}.`);
}
throw result;
@@ -323,7 +319,6 @@ import { convertRepo } from './convert';
}
}

// https://gitlab.com/AlexTugarev/gp-test/issues/1
protected async handleIssueContext(user: User, host: string, owner: string, repoName: string, nr: number): Promise<IssueContext> {
const ctxPromise = this.handleDefaultContext(user, host, owner, repoName);
const result = await this.giteaApi.run<Gitea.Issue>(user, async g => {
@@ -342,7 +337,6 @@ import { convertRepo } from './convert';
};
}

// https://gitlab.com/AlexTugarev/gp-test/-/commit/80948e8cc8f0e851e89a10bc7c2ee234d1a5fbe7
protected async handleCommitContext(user: User, host: string, owner: string, repoName: string, sha: string): Promise<NavigatorContext> {
const repository = await this.fetchRepo(user, owner, repoName);
if (Gitea.ApiError.is(repository)) {
14 changes: 14 additions & 0 deletions components/server/src/gitea/gitea-repository-provider.ts
Original file line number Diff line number Diff line change
@@ -109,4 +109,18 @@ export class GiteaRepositoryProvider implements RepositoryProvider {
// TODO: do we need the html url or clone urls?
return (result || []).map((repo) => repo.html_url || '').filter(s => s !== "")
}

async hasReadAccess(user: User, owner: string, repo: string): Promise<boolean> {
try {
// If we can "see" a project we are allowed to read it
const api = await this.giteaApi;
const response = await api.run(user, (g => g.repos.repoGet(owner, repo)));
if (Gitea.ApiError.is(response)) {
return false;
}
return true;
} catch (err) {
return false;
}
}
}
1 change: 1 addition & 0 deletions components/server/src/gitea/gitea-urls.ts
Original file line number Diff line number Diff line change
@@ -9,5 +9,6 @@ export function oauthUrls(host: string) {
return {
authorizationUrl: `https://${host}/login/oauth/authorize`,
tokenUrl: `https://${host}/login/oauth/access_token`,
settingsUrl: `https://${host}/user/settings/applications`,
}
}