Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • add_route_assignments
  • ask-user-to-delete-exercises-on-duplicates
  • bedran_exercise-list
  • jw_sonar
  • jw_sonar_backup
  • main
  • update-dependencies
  • v6.0.0
  • 2.0.0
  • 2.1.0
  • 2.2.0
  • 3.0.0
  • 3.0.1
  • 3.1.0
  • 3.1.1
  • 3.1.2
  • 3.1.3
  • 3.2.0
  • 3.3.0
  • 3.4.0
  • 3.4.1
  • 3.4.2
  • 3.5.0
  • 3.5.1
  • 3.5.2
  • 3.5.3
  • 4.0.0
  • 4.1.0
  • 5.0.0
  • 5.0.1
  • 6.0.0-dev
  • v1.0.1
32 results

Target

Select target project
  • Dojo_Project_Nguyen/backend/dojobackendapi
  • dojo_project/projects/backend/dojobackendapi
2 results
Select Git revision
  • add_route_assignments
  • ask-user-to-delete-exercises-on-duplicates
  • bedran_exercise-list
  • jw_sonar
  • jw_sonar_backup
  • main
  • update-dependencies
  • v6.0.0
  • 2.0.0
  • 2.1.0
  • 2.2.0
  • 3.0.0
  • 3.0.1
  • 3.1.0
  • 3.1.1
  • 3.1.2
  • 3.1.3
  • 3.2.0
  • 3.3.0
  • 3.4.0
  • 3.4.1
  • 3.4.2
  • 3.5.0
  • 3.5.1
  • 3.5.2
  • 3.5.3
  • 4.0.0
  • 4.1.0
  • 5.0.0
  • 5.0.1
  • 6.0.0-dev
  • v1.0.1
32 results
Show changes
Commits on Source (1)
{
// 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
info:
title: Dojo API
version: 4.0.0
version: 4.1.0
description: |
**Backend API of the Dojo project.**
......
......@@ -41,7 +41,7 @@ class GlobalHelper {
}
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) {
......
......@@ -24,16 +24,27 @@ class GitlabManager extends SharedGitlabManager {
return profileApi.Users.showCurrentUser();
} catch ( e ) {
logger.error(JSON.stringify(e));
return undefined;
}
}
getRepositoryMembers(idOrNamespace: string): Promise<Array<MemberSchema>> {
return this.api.ProjectMembers.all(idOrNamespace, { includeInherited: true });
async getRepositoryMembers(idOrNamespace: string): Promise<Array<MemberSchema>> {
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>> {
return this.api.ProjectReleases.all(repoId);
async getRepositoryReleases(repoId: number): Promise<Array<ReleaseSchema>> {
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> {
......@@ -51,57 +62,92 @@ 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> {
return this.api.Projects.create({
name : name,
description : description,
importUrl : importUrl,
initializeWithReadme: initializeWithReadme,
namespaceId : namespace,
sharedRunnersEnabled: sharedRunnersEnabled,
visibility : visibility,
wikiAccessLevel : wikiEnabled ? 'enabled' : 'disabled'
});
async createRepository(name: string, description: string, visibility: 'public' | 'internal' | 'private', initializeWithReadme: boolean, namespace: number, sharedRunnersEnabled: boolean, wikiEnabled: boolean, importUrl: string): Promise<ProjectSchema> {
try {
return await this.api.Projects.create({
name : name,
description : description,
importUrl : importUrl,
initializeWithReadme: initializeWithReadme,
namespaceId : namespace,
sharedRunnersEnabled: sharedRunnersEnabled,
visibility : visibility,
wikiAccessLevel : wikiEnabled ? 'enabled' : 'disabled'
});
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
}
deleteRepository(repoId: number): Promise<void> {
return this.api.Projects.remove(repoId);
async deleteRepository(repoId: number): Promise<void> {
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> {
return this.api.Projects.fork(forkId, {
name : name,
path : path,
description: description,
namespaceId: namespace,
visibility : visibility
});
async forkRepository(forkId: number, name: string, path: string, description: string, visibility: 'public' | 'internal' | 'private', namespace: number): Promise<ProjectSchema> {
try {
return await this.api.Projects.fork(forkId, {
name : name,
path : path,
description: description,
namespaceId: namespace,
visibility : visibility
});
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
}
editRepository(repoId: number, newAttributes: EditProjectOptions): Promise<ProjectSchema> {
return this.api.Projects.edit(repoId, newAttributes);
async editRepository(repoId: number, newAttributes: EditProjectOptions): Promise<ProjectSchema> {
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> {
return this.editRepository(repoId, { visibility: visibility });
}
addRepositoryMember(repoId: number, userId: number, accessLevel: Exclude<AccessLevel, AccessLevel.ADMIN>): Promise<MemberSchema> {
return this.api.ProjectMembers.add(repoId, userId, accessLevel);
async addRepositoryMember(repoId: number, userId: number, accessLevel: Exclude<AccessLevel, AccessLevel.ADMIN>): Promise<MemberSchema> {
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> {
return this.api.ProjectVariables.create(repoId, key, value, {
variableType: 'env_var',
protected : isProtected,
masked : isMasked
});
async addRepositoryVariable(repoId: number, key: string, value: string, isProtected: boolean, isMasked: boolean): Promise<ProjectVariableSchema> {
try {
return await this.api.ProjectVariables.create(repoId, key, value, {
variableType: 'env_var',
protected : isProtected,
masked : isMasked
});
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
}
addRepositoryBadge(repoId: number, linkUrl: string, imageUrl: string, name: string): Promise<ProjectBadgeSchema> {
return this.api.ProjectBadges.add(repoId, linkUrl, imageUrl, {
name: name
});
async addRepositoryBadge(repoId: number, linkUrl: string, imageUrl: string, name: string): Promise<ProjectBadgeSchema> {
try {
return await this.api.ProjectBadges.add(repoId, linkUrl, imageUrl, {
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> {
......@@ -143,34 +189,54 @@ class GitlabManager extends SharedGitlabManager {
}
}
protectBranch(repoId: number, branchName: string, allowForcePush: boolean, allowedToMerge: ProtectedBranchAccessLevel, allowedToPush: ProtectedBranchAccessLevel, allowedToUnprotect: ProtectedBranchAccessLevel): Promise<ProtectedBranchSchema> {
return this.api.ProtectedBranches.protect(repoId, branchName, {
allowForcePush : allowForcePush,
mergeAccessLevel : allowedToMerge,
pushAccessLevel : allowedToPush,
unprotectAccessLevel: allowedToUnprotect
});
async protectBranch(repoId: number, branchName: string, allowForcePush: boolean, allowedToMerge: ProtectedBranchAccessLevel, allowedToPush: ProtectedBranchAccessLevel, allowedToUnprotect: ProtectedBranchAccessLevel): Promise<ProtectedBranchSchema> {
try {
return await this.api.ProtectedBranches.protect(repoId, branchName, {
allowForcePush : allowForcePush,
mergeAccessLevel : allowedToMerge,
pushAccessLevel : allowedToPush,
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>> {
return this.api.Repositories.allRepositoryTrees(repoId, {
recursive: recursive,
ref : branch
});
async getRepositoryTree(repoId: number, recursive: boolean = true, branch: string = 'main'): Promise<Array<RepositoryTreeSchema>> {
try {
return await this.api.Repositories.allRepositoryTrees(repoId, {
recursive: recursive,
ref : branch
});
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
}
getFile(repoId: number, filePath: string, branch: string = 'main'): Promise<RepositoryFileExpandedSchema> {
return this.api.RepositoryFiles.show(repoId, filePath, branch);
async getFile(repoId: number, filePath: string, branch: string = 'main'): Promise<RepositoryFileExpandedSchema> {
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> {
const gitFunction = create ? this.api.RepositoryFiles.create.bind(this.api) : this.api.RepositoryFiles.edit.bind(this.api);
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);
return gitFunction(repoId, filePath, branch, fileBase64, commitMessage, {
encoding : 'base64',
authorName : authorName,
authorEmail: authorMail
});
return await gitFunction(repoId, filePath, branch, fileBase64, commitMessage, {
encoding : 'base64',
authorName : authorName,
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> {
......@@ -181,11 +247,16 @@ class GitlabManager extends SharedGitlabManager {
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> {
return this.api.RepositoryFiles.remove(repoId, filePath, branch, commitMessage, {
authorName : authorName,
authorEmail: authorMail
});
async deleteFile(repoId: number, filePath: string, commitMessage: string, branch: string = 'main', authorName: string = 'Dojo', authorMail: string | undefined = undefined): Promise<void> {
try {
return await this.api.RepositoryFiles.remove(repoId, filePath, branch, commitMessage, {
authorName : authorName,
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'
import DojoModelsHelper from '../helpers/DojoModelsHelper.js';
import * as Gitlab from '@gitbeaker/rest';
import { GitbeakerRequestError } from '@gitbeaker/requester-utils';
import SharedConfig from '../shared/config/SharedConfig.js';
class AssignmentRoutes implements RoutesManager {
......@@ -203,10 +204,11 @@ class AssignmentRoutes implements RoutesManager {
} else if ( isUpdate && !req.boundParams.exercise?.isCorrection ) {
return req.session.sendResponse(res, StatusCodes.BAD_REQUEST, undefined, 'This exercise is not a correction', DojoStatusCode.EXERCISE_CORRECTION_NOT_EXIST);
}
const lastCommit = await GitlabManager.getRepositoryLastCommit(req.boundParams.exercise!.gitlabId);
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');
}
......