Skip to content
Snippets Groups Projects
Commit 3e6e6ff2 authored by michael.minelli's avatar michael.minelli
Browse files

Fix bug on duplicate repo creation

parent e3745cdc
No related branches found
No related tags found
No related merge requests found
Pipeline #32084 passed
{
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
// Pointez pour afficher la description des attributs existants.
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "tsx",
"type": "node",
"request": "launch",
// Debug current file in VSCode
"program": "src/app.ts",
/*
Path to tsx binary
Assuming locally installed
*/
"runtimeExecutable": "tsx",
/*
Open terminal when debugging starts (Optional)
Useful to see console.logs
*/
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
// Files to exclude from debugger (e.g. call stack)
"skipFiles": [
// Node.js internal core modules
"<node_internals>/**",
// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**",
],
}
]
}
\ No newline at end of file
openapi: 3.1.0 openapi: 3.1.0
info: info:
title: Dojo API title: Dojo API
version: 4.0.0 version: 4.1.0
description: | description: |
**Backend API of the Dojo project.** **Backend API of the Dojo project.**
......
...@@ -41,7 +41,7 @@ class GlobalHelper { ...@@ -41,7 +41,7 @@ class GlobalHelper {
} }
isRepoNameAlreadyTaken(errorDescription: unknown) { isRepoNameAlreadyTaken(errorDescription: unknown) {
return errorDescription instanceof Object && 'name' in errorDescription && errorDescription.name instanceof Array && errorDescription.name.length > 0 && errorDescription.name[0] === 'has already been taken'; return errorDescription instanceof Array && errorDescription.length > 0 && (errorDescription[0] as string).includes('has already been taken');
} }
addRepoMember(repositoryId: number) { addRepoMember(repositoryId: number) {
......
...@@ -24,16 +24,27 @@ class GitlabManager extends SharedGitlabManager { ...@@ -24,16 +24,27 @@ class GitlabManager extends SharedGitlabManager {
return profileApi.Users.showCurrentUser(); return profileApi.Users.showCurrentUser();
} catch ( e ) { } catch ( e ) {
logger.error(JSON.stringify(e));
return undefined; return undefined;
} }
} }
getRepositoryMembers(idOrNamespace: string): Promise<Array<MemberSchema>> { async getRepositoryMembers(idOrNamespace: string): Promise<Array<MemberSchema>> {
return this.api.ProjectMembers.all(idOrNamespace, { includeInherited: true }); try {
return await this.api.ProjectMembers.all(idOrNamespace, { includeInherited: true });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
getRepositoryReleases(repoId: number): Promise<Array<ReleaseSchema>> { async getRepositoryReleases(repoId: number): Promise<Array<ReleaseSchema>> {
return this.api.ProjectReleases.all(repoId); try {
return await this.api.ProjectReleases.all(repoId);
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
async getRepositoryLastCommit(repoId: number, branch: string = 'main'): Promise<CommitSchema | undefined> { async getRepositoryLastCommit(repoId: number, branch: string = 'main'): Promise<CommitSchema | undefined> {
...@@ -51,8 +62,9 @@ class GitlabManager extends SharedGitlabManager { ...@@ -51,8 +62,9 @@ class GitlabManager extends SharedGitlabManager {
} }
} }
createRepository(name: string, description: string, visibility: 'public' | 'internal' | 'private', initializeWithReadme: boolean, namespace: number, sharedRunnersEnabled: boolean, wikiEnabled: boolean, importUrl: string): Promise<ProjectSchema> { async createRepository(name: string, description: string, visibility: 'public' | 'internal' | 'private', initializeWithReadme: boolean, namespace: number, sharedRunnersEnabled: boolean, wikiEnabled: boolean, importUrl: string): Promise<ProjectSchema> {
return this.api.Projects.create({ try {
return await this.api.Projects.create({
name : name, name : name,
description : description, description : description,
importUrl : importUrl, importUrl : importUrl,
...@@ -62,46 +74,80 @@ class GitlabManager extends SharedGitlabManager { ...@@ -62,46 +74,80 @@ class GitlabManager extends SharedGitlabManager {
visibility : visibility, visibility : visibility,
wikiAccessLevel : wikiEnabled ? 'enabled' : 'disabled' wikiAccessLevel : wikiEnabled ? 'enabled' : 'disabled'
}); });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
deleteRepository(repoId: number): Promise<void> { async deleteRepository(repoId: number): Promise<void> {
return this.api.Projects.remove(repoId); try {
return await this.api.Projects.remove(repoId);
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
forkRepository(forkId: number, name: string, path: string, description: string, visibility: 'public' | 'internal' | 'private', namespace: number): Promise<ProjectSchema> { async forkRepository(forkId: number, name: string, path: string, description: string, visibility: 'public' | 'internal' | 'private', namespace: number): Promise<ProjectSchema> {
return this.api.Projects.fork(forkId, { try {
return await this.api.Projects.fork(forkId, {
name : name, name : name,
path : path, path : path,
description: description, description: description,
namespaceId: namespace, namespaceId: namespace,
visibility : visibility visibility : visibility
}); });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
editRepository(repoId: number, newAttributes: EditProjectOptions): Promise<ProjectSchema> { async editRepository(repoId: number, newAttributes: EditProjectOptions): Promise<ProjectSchema> {
return this.api.Projects.edit(repoId, newAttributes); try {
return await this.api.Projects.edit(repoId, newAttributes);
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
changeRepositoryVisibility(repoId: number, visibility: GitlabVisibility): Promise<ProjectSchema> { changeRepositoryVisibility(repoId: number, visibility: GitlabVisibility): Promise<ProjectSchema> {
return this.editRepository(repoId, { visibility: visibility }); return this.editRepository(repoId, { visibility: visibility });
} }
addRepositoryMember(repoId: number, userId: number, accessLevel: Exclude<AccessLevel, AccessLevel.ADMIN>): Promise<MemberSchema> { async addRepositoryMember(repoId: number, userId: number, accessLevel: Exclude<AccessLevel, AccessLevel.ADMIN>): Promise<MemberSchema> {
return this.api.ProjectMembers.add(repoId, userId, accessLevel); try {
return await this.api.ProjectMembers.add(repoId, userId, accessLevel);
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
addRepositoryVariable(repoId: number, key: string, value: string, isProtected: boolean, isMasked: boolean): Promise<ProjectVariableSchema> { async addRepositoryVariable(repoId: number, key: string, value: string, isProtected: boolean, isMasked: boolean): Promise<ProjectVariableSchema> {
return this.api.ProjectVariables.create(repoId, key, value, { try {
return await this.api.ProjectVariables.create(repoId, key, value, {
variableType: 'env_var', variableType: 'env_var',
protected : isProtected, protected : isProtected,
masked : isMasked masked : isMasked
}); });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
addRepositoryBadge(repoId: number, linkUrl: string, imageUrl: string, name: string): Promise<ProjectBadgeSchema> { async addRepositoryBadge(repoId: number, linkUrl: string, imageUrl: string, name: string): Promise<ProjectBadgeSchema> {
return this.api.ProjectBadges.add(repoId, linkUrl, imageUrl, { try {
return await this.api.ProjectBadges.add(repoId, linkUrl, imageUrl, {
name: name name: name
}); });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
async checkTemplateAccess(projectIdOrNamespace: string, req: express.Request, res?: express.Response): Promise<boolean> { async checkTemplateAccess(projectIdOrNamespace: string, req: express.Request, res?: express.Response): Promise<boolean> {
...@@ -143,34 +189,54 @@ class GitlabManager extends SharedGitlabManager { ...@@ -143,34 +189,54 @@ class GitlabManager extends SharedGitlabManager {
} }
} }
protectBranch(repoId: number, branchName: string, allowForcePush: boolean, allowedToMerge: ProtectedBranchAccessLevel, allowedToPush: ProtectedBranchAccessLevel, allowedToUnprotect: ProtectedBranchAccessLevel): Promise<ProtectedBranchSchema> { async protectBranch(repoId: number, branchName: string, allowForcePush: boolean, allowedToMerge: ProtectedBranchAccessLevel, allowedToPush: ProtectedBranchAccessLevel, allowedToUnprotect: ProtectedBranchAccessLevel): Promise<ProtectedBranchSchema> {
return this.api.ProtectedBranches.protect(repoId, branchName, { try {
return await this.api.ProtectedBranches.protect(repoId, branchName, {
allowForcePush : allowForcePush, allowForcePush : allowForcePush,
mergeAccessLevel : allowedToMerge, mergeAccessLevel : allowedToMerge,
pushAccessLevel : allowedToPush, pushAccessLevel : allowedToPush,
unprotectAccessLevel: allowedToUnprotect unprotectAccessLevel: allowedToUnprotect
}); });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
getRepositoryTree(repoId: number, recursive: boolean = true, branch: string = 'main'): Promise<Array<RepositoryTreeSchema>> { async getRepositoryTree(repoId: number, recursive: boolean = true, branch: string = 'main'): Promise<Array<RepositoryTreeSchema>> {
return this.api.Repositories.allRepositoryTrees(repoId, { try {
return await this.api.Repositories.allRepositoryTrees(repoId, {
recursive: recursive, recursive: recursive,
ref : branch ref : branch
}); });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
getFile(repoId: number, filePath: string, branch: string = 'main'): Promise<RepositoryFileExpandedSchema> { async getFile(repoId: number, filePath: string, branch: string = 'main'): Promise<RepositoryFileExpandedSchema> {
return this.api.RepositoryFiles.show(repoId, filePath, branch); try {
return await this.api.RepositoryFiles.show(repoId, filePath, branch);
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
private createUpdateFile(create: boolean, repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<RepositoryFileSchema> { private async createUpdateFile(create: boolean, repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<RepositoryFileSchema> {
try {
const gitFunction = create ? this.api.RepositoryFiles.create.bind(this.api) : this.api.RepositoryFiles.edit.bind(this.api); const gitFunction = create ? this.api.RepositoryFiles.create.bind(this.api) : this.api.RepositoryFiles.edit.bind(this.api);
return gitFunction(repoId, filePath, branch, fileBase64, commitMessage, { return await gitFunction(repoId, filePath, branch, fileBase64, commitMessage, {
encoding : 'base64', encoding : 'base64',
authorName : authorName, authorName : authorName,
authorEmail: authorMail authorEmail: authorMail
}); });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
createFile(repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<RepositoryFileSchema> { createFile(repoId: number, filePath: string, fileBase64: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<RepositoryFileSchema> {
...@@ -181,11 +247,16 @@ class GitlabManager extends SharedGitlabManager { ...@@ -181,11 +247,16 @@ class GitlabManager extends SharedGitlabManager {
return this.createUpdateFile(false, repoId, filePath, fileBase64, commitMessage, branch, authorName, authorMail); return this.createUpdateFile(false, repoId, filePath, fileBase64, commitMessage, branch, authorName, authorMail);
} }
deleteFile(repoId: number, filePath: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<void> { async deleteFile(repoId: number, filePath: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<void> {
return this.api.RepositoryFiles.remove(repoId, filePath, branch, commitMessage, { try {
return await this.api.RepositoryFiles.remove(repoId, filePath, branch, commitMessage, {
authorName : authorName, authorName : authorName,
authorEmail: authorMail authorEmail: authorMail
}); });
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
} }
} }
......
...@@ -22,6 +22,7 @@ import DojoStatusCode from '../shared/types/Dojo/DojoStatusCode.js' ...@@ -22,6 +22,7 @@ import DojoStatusCode from '../shared/types/Dojo/DojoStatusCode.js'
import DojoModelsHelper from '../helpers/DojoModelsHelper.js'; import DojoModelsHelper from '../helpers/DojoModelsHelper.js';
import * as Gitlab from '@gitbeaker/rest'; import * as Gitlab from '@gitbeaker/rest';
import { GitbeakerRequestError } from '@gitbeaker/requester-utils'; import { GitbeakerRequestError } from '@gitbeaker/requester-utils';
import SharedConfig from '../shared/config/SharedConfig.js';
class AssignmentRoutes implements RoutesManager { class AssignmentRoutes implements RoutesManager {
...@@ -205,8 +206,9 @@ class AssignmentRoutes implements RoutesManager { ...@@ -205,8 +206,9 @@ class AssignmentRoutes implements RoutesManager {
} }
const lastCommit = await GitlabManager.getRepositoryLastCommit(req.boundParams.exercise!.gitlabId); const lastCommit = await GitlabManager.getRepositoryLastCommit(req.boundParams.exercise!.gitlabId);
if ( lastCommit ) { if ( lastCommit ) {
if ( !isUpdate ) { if ( !isUpdate && SharedConfig.production ) { //Disable in dev env because gitlab dev group is private and we can't change visibility of sub projects
await GitlabManager.changeRepositoryVisibility(req.boundParams.exercise!.gitlabId, 'internal'); await GitlabManager.changeRepositoryVisibility(req.boundParams.exercise!.gitlabId, 'internal');
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment