fix: fix github authentification

This commit is contained in:
tdurieux
2024-04-02 09:10:14 +01:00
parent 8a9d2d8395
commit ea96c31e9d
5 changed files with 72 additions and 43 deletions
+11 -4
View File
@@ -15,6 +15,7 @@ import AnonymousError from "./AnonymousError";
import { handleError } from "./routes/route-utils"; import { handleError } from "./routes/route-utils";
import { lookup } from "mime-types"; import { lookup } from "mime-types";
import { FILE_TYPE } from "./storage/Storage"; import { FILE_TYPE } from "./storage/Storage";
import GitHubBase from "./source/GitHubBase";
/** /**
* Represent a file in a anonymized repository * Represent a file in a anonymized repository
@@ -224,9 +225,13 @@ export default class AnonymizedFile {
.startActiveSpan("anonymizedContent", async (span) => { .startActiveSpan("anonymizedContent", async (span) => {
span.setAttribute("anonymizedPath", this.anonymizedPath); span.setAttribute("anonymizedPath", this.anonymizedPath);
const content = await this.content(); const content = await this.content();
return content.pipe(new AnonymizeTransformer(this)).on("close", () => { return content
span.end(); .pipe(
}); this.repository.generateAnonymizeTransformer(this.anonymizedPath)
)
.on("close", () => {
span.end();
});
}); });
} }
@@ -259,7 +264,9 @@ export default class AnonymizedFile {
res.contentType("text/plain"); res.contentType("text/plain");
} }
res.header("Accept-Ranges", "none"); res.header("Accept-Ranges", "none");
const anonymizer = new AnonymizeTransformer(this); const anonymizer = this.repository.generateAnonymizeTransformer(
this.anonymizedPath
);
anonymizer.once("transform", (data) => { anonymizer.once("transform", (data) => {
if (!mime && data.isText) { if (!mime && data.isText) {
res.contentType("text/plain"); res.contentType("text/plain");
+31 -13
View File
@@ -15,7 +15,6 @@ import ConferenceModel from "./database/conference/conferences.model";
import AnonymousError from "./AnonymousError"; import AnonymousError from "./AnonymousError";
import { downloadQueue } from "./queue"; import { downloadQueue } from "./queue";
import { isConnected } from "./database/database"; import { isConnected } from "./database/database";
import AnonymizedFile from "./AnonymizedFile";
import AnonymizedRepositoryModel from "./database/anonymizedRepositories/anonymizedRepositories.model"; import AnonymizedRepositoryModel from "./database/anonymizedRepositories/anonymizedRepositories.model";
import { getRepositoryFromGitHub } from "./source/GitHubRepository"; import { getRepositoryFromGitHub } from "./source/GitHubRepository";
import config from "../config"; import config from "../config";
@@ -71,6 +70,15 @@ export default class Repository {
}); });
} }
this.owner = new User(new UserModel({ _id: data.owner })); this.owner = new User(new UserModel({ _id: data.owner }));
if (this.source instanceof GitHubBase) {
const originalToken = this._model.source.accessToken;
this.source.getToken(this.owner.id).then((token) => {
if (originalToken != token) {
this._model.source.accessToken = token;
this._model.save();
}
});
}
this.owner.model.isNew = false; this.owner.model.isNew = false;
} }
@@ -175,12 +183,19 @@ export default class Repository {
return storage.archive(this.repoId, "", { return storage.archive(this.repoId, "", {
format: "zip", format: "zip",
fileTransformer: (filename: string) => fileTransformer: (filename: string) =>
new AnonymizeTransformer( this.generateAnonymizeTransformer(filename),
new AnonymizedFile({ });
repository: this, }
anonymizedPath: filename,
}) generateAnonymizeTransformer(filePath: string) {
), return new AnonymizeTransformer({
filePath: filePath,
terms: this.options.terms,
image: this.options.image,
link: this.options.link,
repoId: this.repoId,
repoName: (this.source as GitHubBase).githubRepository?.fullName,
branchName: (this.source as GitHubBase).branch?.name || "main",
}); });
} }
@@ -202,7 +217,7 @@ export default class Repository {
) { ) {
// Only GitHubBase can be update for the moment // Only GitHubBase can be update for the moment
if (this.source instanceof GitHubBase) { if (this.source instanceof GitHubBase) {
const token = await this.source.getToken(); const token = await this.source.getToken(this.owner.id);
const branches = await this.source.githubRepository.branches({ const branches = await this.source.githubRepository.branches({
force: true, force: true,
accessToken: token, accessToken: token,
@@ -226,10 +241,13 @@ export default class Repository {
accessToken: token, accessToken: token,
} }
); );
if (commitInfo.commit.author?.date) { if (
this._model.source.commitDate = new Date( commitInfo.commit?.author?.date ||
commitInfo.commit.author?.date commitInfo.commit?.committer?.date
); ) {
const d = (commitInfo.commit?.author?.date ||
commitInfo.commit.committer?.date) as string;
this._model.source.commitDate = new Date(d);
} }
branch.commit = newCommit; branch.commit = newCommit;
@@ -252,7 +270,7 @@ export default class Repository {
if (this.source.type == "GitHubDownload") { if (this.source.type == "GitHubDownload") {
const repository = await getRepositoryFromGitHub({ const repository = await getRepositoryFromGitHub({
accessToken: await this.source.getToken(), accessToken: await this.source.getToken(this.owner.id),
owner: this.source.githubRepository.owner, owner: this.source.githubRepository.owner,
repo: this.source.githubRepository.repo, repo: this.source.githubRepository.repo,
}); });
+9 -15
View File
@@ -36,32 +36,26 @@ export class AnonymizeTransformer extends Transform {
public wasAnonimized = false; public wasAnonimized = false;
public isText: boolean | null = null; public isText: boolean | null = null;
constructor(private readonly file: AnonymizedFile) { constructor(
private readonly opt: {
filePath: string;
} & ConstructorParameters<typeof ContentAnonimizer>[1]
) {
super(); super();
this.isText = isTextFile(this.file.anonymizedPath); this.isText = isTextFile(this.opt.filePath);
} }
_transform(chunk: Buffer, encoding: string, callback: () => void) { _transform(chunk: Buffer, encoding: string, callback: () => void) {
trace trace
.getTracer("ano-file") .getTracer("ano-file")
.startActiveSpan("AnonymizeTransformer.transform", async (span) => { .startActiveSpan("AnonymizeTransformer.transform", async (span) => {
span.setAttribute("path", this.file.anonymizedPath); span.setAttribute("path", this.opt.filePath);
if (this.isText === null) { if (this.isText === null) {
this.isText = isTextFile(this.file.anonymizedPath, chunk); this.isText = isTextFile(this.opt.filePath, chunk);
} }
if (this.isText) { if (this.isText) {
const anonimizer = new ContentAnonimizer(chunk.toString(), { const anonimizer = new ContentAnonimizer(chunk.toString(), this.opt);
repoId: this.file.repository.repoId,
image: this.file.repository.options.image,
link: this.file.repository.options.link,
terms: this.file.repository.options.terms,
repoName: (this.file.repository.source as GitHubBase)
.githubRepository?.fullName,
branchName:
(this.file.repository.source as GitHubBase).branch?.name ||
"main",
});
anonimizer.anonymize(); anonimizer.anonymize();
if (anonimizer.wasAnonymized) { if (anonimizer.wasAnonymized) {
this.wasAnonimized = true; this.wasAnonimized = true;
+7 -4
View File
@@ -37,13 +37,13 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
}); });
} }
async download(progress?: (status: string) => void) { async download(token: string, progress?: (status: string) => void) {
const span = trace.getTracer("ano-file").startSpan("GHDownload.download"); const span = trace.getTracer("ano-file").startSpan("GHDownload.download");
span.setAttribute("repoId", this.githubRepository.fullName || ""); span.setAttribute("repoId", this.githubRepository.fullName || "");
try { try {
let response: OctokitResponse<unknown, number>; let response: OctokitResponse<unknown, number>;
try { try {
response = await this._getZipUrl(await this.getToken()); response = await this._getZipUrl(token);
} catch (error) { } catch (error) {
span.recordException(error as Error); span.recordException(error as Error);
throw new AnonymousError("repo_not_accessible", { throw new AnonymousError("repo_not_accessible", {
@@ -117,7 +117,10 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
await file.originalPath(); await file.originalPath();
// the cache is not ready, we need to download the repository // the cache is not ready, we need to download the repository
await this.download(progress); await this.download(
await this.getToken(file.repository.owner.id),
progress
);
return storage.read(this.repoId, file.filePath); return storage.read(this.repoId, file.filePath);
} finally { } finally {
span.end(); span.end();
@@ -126,7 +129,7 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
async getFiles() { async getFiles() {
if ((await storage.exists(this.repoId)) === FILE_TYPE.NOT_FOUND) { if ((await storage.exists(this.repoId)) === FILE_TYPE.NOT_FOUND) {
await this.download(); await this.download(await this.getToken());
} }
return storage.listFiles(this.repoId); return storage.listFiles(this.repoId);
} }
+14 -7
View File
@@ -129,13 +129,14 @@ export default class GitHubStream extends GitHubBase implements SourceBase {
span.setAttribute("repoName", this.githubRepository.fullName || ""); span.setAttribute("repoName", this.githubRepository.fullName || "");
try { try {
let commit = this.branch?.commit; let commit = this.branch?.commit;
return this.getTree(commit); return this.getTree(await this.getToken(), commit);
} finally { } finally {
span.end(); span.end();
} }
} }
private async getTree( private async getTree(
token: string,
sha: string, sha: string,
truncatedTree: Tree = {}, truncatedTree: Tree = {},
parentPath: string = "", parentPath: string = "",
@@ -151,7 +152,7 @@ export default class GitHubStream extends GitHubBase implements SourceBase {
let ghRes: Awaited<ReturnType<typeof this.getGHTree>>; let ghRes: Awaited<ReturnType<typeof this.getGHTree>>;
try { try {
count.request++; count.request++;
ghRes = await this.getGHTree(sha, { recursive: true }); ghRes = await this.getGHTree(token, sha, { recursive: true });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
span.recordException(error as Error); span.recordException(error as Error);
@@ -177,17 +178,21 @@ export default class GitHubStream extends GitHubBase implements SourceBase {
const tree = this.tree2Tree(ghRes.tree, truncatedTree, parentPath); const tree = this.tree2Tree(ghRes.tree, truncatedTree, parentPath);
count.file += ghRes.tree.length; count.file += ghRes.tree.length;
if (ghRes.truncated) { if (ghRes.truncated) {
await this.getTruncatedTree(sha, tree, parentPath, count); await this.getTruncatedTree(token, sha, tree, parentPath, count);
} }
span.end(); span.end();
return tree; return tree;
} }
private async getGHTree(sha: string, opt = { recursive: true }) { private async getGHTree(
token: string,
sha: string,
opt = { recursive: true }
) {
const span = trace.getTracer("ano-file").startSpan("GHStream.getGHTree"); const span = trace.getTracer("ano-file").startSpan("GHStream.getGHTree");
span.setAttribute("sha", sha); span.setAttribute("sha", sha);
try { try {
const octokit = GitHubBase.octokit(await this.getToken()); const octokit = GitHubBase.octokit(token);
const ghRes = await octokit.git.getTree({ const ghRes = await octokit.git.getTree({
owner: this.githubRepository.owner, owner: this.githubRepository.owner,
repo: this.githubRepository.repo, repo: this.githubRepository.repo,
@@ -201,6 +206,7 @@ export default class GitHubStream extends GitHubBase implements SourceBase {
} }
private async getTruncatedTree( private async getTruncatedTree(
token: string,
sha: string, sha: string,
truncatedTree: Tree = {}, truncatedTree: Tree = {},
parentPath: string = "", parentPath: string = "",
@@ -220,7 +226,7 @@ export default class GitHubStream extends GitHubBase implements SourceBase {
let data = null; let data = null;
try { try {
data = await this.getGHTree(sha, { recursive: false }); data = await this.getGHTree(token, sha, { recursive: false });
this.tree2Tree(data.tree, truncatedTree, parentPath); this.tree2Tree(data.tree, truncatedTree, parentPath);
} catch (error) { } catch (error) {
span.recordException(error as Error); span.recordException(error as Error);
@@ -235,6 +241,7 @@ export default class GitHubStream extends GitHubBase implements SourceBase {
const elementPath = path.join(parentPath, file.path); const elementPath = path.join(parentPath, file.path);
promises.push( promises.push(
this.getTruncatedTree( this.getTruncatedTree(
token,
file.sha, file.sha,
truncatedTree, truncatedTree,
elementPath, elementPath,
@@ -247,7 +254,7 @@ export default class GitHubStream extends GitHubBase implements SourceBase {
await Promise.all(promises); await Promise.all(promises);
} else { } else {
try { try {
const data = await this.getGHTree(sha, { recursive: true }); const data = await this.getGHTree(token, sha, { recursive: true });
this.tree2Tree(data.tree, truncatedTree, parentPath); this.tree2Tree(data.tree, truncatedTree, parentPath);
if (data.truncated) { if (data.truncated) {
// TODO: TRUNCATED // TODO: TRUNCATED