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

OpenAPI => Abort first try

parent a1ab6547
No related branches found
No related tags found
No related merge requests found
......@@ -4,8 +4,8 @@ workspace.xml
Wiki/.idea
ExpressAPI/src/config/Version.ts
openapi.json
redoc.html
OpenAPI.yaml-r
############################ MacOS
......
This diff is collapsed.
......@@ -10,7 +10,7 @@
"dotenv:build" : "npx dotenv-vault local build",
"lint" : "npx eslint .",
"genversion" : "npx genversion -s -e src/config/Version.ts",
"build:openapi" : "npx ts-node src/openapi.ts; npx @redocly/cli build-docs assets/openapi.json --output=assets/redoc.html",
"build:openapi" : "sed -i -r \"1,20 s/^\\([ ]*version:\\).*$/\\1 $(jq -r .version package.json)/\" assets/OpenAPI/OpenAPI.yaml; npx @redocly/cli build-docs assets/OpenAPI/OpenAPI.yaml --output=assets/OpenAPI/redoc.html",
"build:project" : "npm run genversion; npx prisma generate && npx tsc --project ./ && cp -R assets dist/assets",
"build" : "npm run build:openapi; npm run build:project",
"database:migrate" : "npx prisma migrate deploy",
......@@ -51,7 +51,7 @@
"winston" : "^3.8.2"
},
"devDependencies": {
"@redocly/cli" : "^1.4.1",
"@redocly/cli" : "^1.5.0",
"@types/compression" : "^1.7.2",
"@types/cors" : "^2.8.13",
"@types/express" : "^4.17.17",
......@@ -64,14 +64,13 @@
"@types/swagger-ui-express" : "^4.1.6",
"@types/tar-stream" : "^2.2.2",
"@types/uuid" : "^9.0.2",
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser" : "^6.10.0",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser" : "^6.12.0",
"dotenv-vault" : "^1.25.0",
"genversion" : "^3.1.1",
"nodemon" : "^3.0.1",
"npm" : "^9.8.1",
"prisma" : "^5.1.1",
"swagger-autogen" : "^2.23.7",
"ts-node" : "^10.9.1",
"typescript" : "^5.1.6"
}
......
require('./InitialImports'); // ATTENTION : These lines MUST be the first of this file
import swaggerAutogen from 'swagger-autogen';
import { version } from './config/Version';
import Config from './config/Config';
const doc = {
info : {
title : 'Dojo API',
version : version,
description: '**Backend API of the Dojo project.**\n\nSee more information about the projet on [Gitlab](https://githepia.hesge.ch/dojo_project/dojo).',
license : {
name: 'AGPLv3',
url : 'https://githepia.hesge.ch/dojo_project/projects/backend/dojobackendapi/-/blob/main/LICENSE'
},
contact : {
name : 'Michaël Minelli',
email: 'dojo@minelli.me'
}
},
servers : [ {
url : `http://localhost:${ Config.api.port }/`,
description: 'Development'
}, {
url : `http://dojo-test.edu.hesge.ch/dojo/api/`,
description: 'Test (only from HES-GE network)'
}, {
url : `https://rdps.hesge.ch/dojo/api/`,
description: 'Production'
} ],
tags : [ {
name : 'General',
description: ''
}, {
name : 'Session',
description: 'Routes that are used to manage the user\'s session'
}, {
name : 'Gitlab',
description: 'Routes that are used to provide Gitlab informations'
}, {
name : 'Assignment',
description: 'Routes that are used to manage assignments'
}, {
name : 'Exercise',
description: 'Routes that are used to manage exercises'
} ],
consumes : [ 'multipart/form-data' ],
produces : [ 'application/json' ],
components: {
securitySchemes: {
'Clients token' : {
type : 'http',
scheme : 'bearer',
bearerFormat: 'JWT'
},
'ExerciseChecker secret': {
type: 'apiKey',
in : 'header',
name: 'ExerciseSecret'
}
},
schemas : {
DojoBackendResponse: {
$timestamp : '717876000000',
$code : 200,
$description : 'OK',
$sessionToken: 'JWT token (for content, see schema named \'SessionTokenJWT\')',
$data : {}
},
User : {
$id : 142,
name : 'michael.minelli',
mail : 'dojo@minelli.me',
$role : {
'@enum': [ 'STUDENT', 'TEACHING_STAFF', 'ADMIN' ]
},
$gitlabUsername : 'michael.minelli',
gitlabLastInfo : {},
$isTeachingStaff: true,
$isAdmin : true,
$deleted : false,
assignments : [ {
$ref: '#/components/schemas/Assignment'
} ],
exercises : [ {
$ref: '#/components/schemas/Exercise'
} ]
},
Assignment : {
$name : 'C_Hello_World',
$gitlabId : 30992,
$gitlabLink : 'https://githepia.hesge.ch/dojo_project',
$gitlabCreationInfo: {},
$gitlabLastInfo : {},
$gitlabLastInfoDate: '1992-09-30 19:00:00.000',
$published : true,
$staff : [ {
$ref: '#/components/schemas/User'
} ],
$exercises : [ {
$ref: '#/components/schemas/Exercise'
} ]
},
Exercise : {
$id : 'eb5f2182-f5b1-42a9-80fc-cad384571053',
$assignmentName : 'C_Hello_World',
$name : 'DojoEx - C_Hello_World - michael.minelli',
$gitlabId : 93092,
$gitlabLink : 'https://githepia.hesge.ch/dojo_project/dojo',
$gitlabCreationInfo: {},
$gitlabLastInfo : {},
$gitlabLastInfoDate: '1992-09-30 19:00:00.000'
},
SessionTokenJWT : {
$profile: {
$ref: '#/components/schemas/User'
},
$iat : '1700749215'
}
}
}
};
const options = {
openapi : '3.1.0',
autoHeader: false,
autoBody : false
};
const outputFile = '../assets/openapi.json';
const routes = [ './routes/*.ts' ];
swaggerAutogen(options)(outputFile, routes, doc);
\ No newline at end of file
......@@ -55,11 +55,6 @@ class AssignmentRoutes implements RoutesManager {
// Get an assignment by its name or gitlab url
private async getAssignment(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Assignment']
#swagger.description = 'Endpoint to get the specific user.'
*/
const assignment: Assignment | undefined = req.boundParams.assignment;
if ( assignment && !assignment.published && !await AssignmentManager.isUserAllowedToAccessAssignment(assignment, req.session.profile) ) {
......@@ -90,11 +85,6 @@ class AssignmentRoutes implements RoutesManager {
}
private async createAssignment(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Assignment']
#swagger.description = 'Endpoint to get the specific user.'
*/
const params: {
name: string, members: Array<GitlabUser>, template: string
} = req.body;
......@@ -178,20 +168,10 @@ class AssignmentRoutes implements RoutesManager {
}
private async publishAssignment(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Assignment']
#swagger.description = 'Endpoint to get the specific user.'
*/
return this.changeAssignmentPublishedStatus(true)(req, res);
}
private async unpublishAssignment(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Assignment']
#swagger.description = 'Endpoint to get the specific user.'
*/
return this.changeAssignmentPublishedStatus(false)(req, res);
}
......
......@@ -11,29 +11,10 @@ class BaseRoutes implements RoutesManager {
}
private async homepage(req: express.Request, res: express.Response) {
/*
#swagger.ignore = true
*/
return req.session.sendResponse(res, StatusCodes.OK);
}
private async healthCheck(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['General']
#swagger.summary = 'Health check'
#swagger.description = 'This route can be used to check if the server is up and running.'
#swagger.responses[200] = {
content: {
"application/json": {
schema:{
$ref: "#/components/schemas/DojoBackendResponse"
}
}
}
}
*/
return req.session.sendResponse(res, StatusCodes.OK);
}
}
......
......@@ -85,11 +85,6 @@ class ExerciseRoutes implements RoutesManager {
}
private async createExercise(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Exercise']
#swagger.description = 'Endpoint to get the specific user.'
*/
const params: { members: Array<GitlabUser> } = req.body;
params.members = [ await req.session.profile.gitlabProfile!.value, ...params.members ].removeObjectDuplicates(gitlabUser => gitlabUser.id);
const assignment: Assignment = req.boundParams.assignment!;
......@@ -190,34 +185,6 @@ class ExerciseRoutes implements RoutesManager {
}
private async getAssignment(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Exercise', 'Assignment']
#swagger.description = 'Endpoint to get the specific user.'
#swagger.responses[200] = {
description: "Some description...",
content: {
"application/json": {
schema:{
allOf: [
{ $ref: "#/components/schemas/DojoBackendResponse" },
{
type : 'object',
properties : {
data: {
type: 'object',
properties: {
assignment: { $ref: "#/components/schemas/Assignment" }
}
}
}
}
]
}
}
}
}
*/
const repoTree: Array<GitlabTreeFile> = await GitlabManager.getRepositoryTree(req.boundParams.exercise!.assignment.gitlabId);
let assignmentHjsonFile!: GitlabFile;
......@@ -254,11 +221,6 @@ class ExerciseRoutes implements RoutesManager {
}
private async createResult(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Exercise']
#swagger.description = 'Endpoint to get the specific user.'
*/
const params: { exitCode: number, commit: Record<string, string>, results: ExerciseResultsFile, files: Array<IFileDirStat>, archiveBase64: string } = req.body;
const exercise: Exercise = req.boundParams.exercise!;
......
......@@ -12,10 +12,7 @@ class GitlabRoutes implements RoutesManager {
}
private async checkTemplateAccess(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Gitlab']
#swagger.description = 'Endpoint to get the specific user.'
*/
const gitlabProjectIdOrNamespace: string = req.params.gitlabProjectIdOrNamespace;
const idOrNamespace: string = req.params.idOrNamespace;
......
......@@ -38,51 +38,6 @@ class SessionRoutes implements RoutesManager {
}
private async login(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Session']
#swagger.summary = 'Login to Dojo app'
#swagger.description = 'This route can be used to connect the user to the backend and retrieve informations about his access rights.'
#swagger.requestBody = {
content: {
"multipart/form-data": {
schema: {
type: 'object',
properties: {
accessToken: {
type: 'string',
format: 'Gitlab access token'
},
refreshToken: {
type: 'string',
format: 'Gitlab refresh token'
}
},
required: ['accessToken', 'refreshToken']
}
}
}
}
#swagger.responses[200] = {
content: {
"application/json": {
schema:{
$ref: "#/components/schemas/DojoBackendResponse"
}
}
}
}
#swagger.responses[404] = {
description: "Can't retrieve user informations from Gitlab with the provided access token.",
content: {
"application/json": {
schema:{
$ref: "#/components/schemas/DojoBackendResponse"
}
}
}
}
*/
try {
const params: {
accessToken: string, refreshToken: string
......@@ -104,90 +59,6 @@ class SessionRoutes implements RoutesManager {
}
private async refreshTokens(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Session']
#swagger.summary = 'Refresh tokens'
#swagger.description = 'This route can be used to refresh the session. Gitlab tokens will be refreshed and a new Dojo backend JWT token will be provided.'
#swagger.requestBody = {
content: {
"multipart/form-data": {
schema: {
type: 'object',
properties: {
refreshToken: {
type: 'string',
format: 'Gitlab refresh token'
}
},
required: ['refreshToken']
}
}
}
}
#swagger.responses[200] = {
description: 'The new Gitlab tokens as returned by Gitlab API.',
content: {
"application/json": {
schema:{
allOf: [
{ $ref: "#/components/schemas/DojoBackendResponse" },
{
type : 'object',
properties : {
data: {
type: 'object',
properties: {
"access_token": {
"type": "string",
"example": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54"
},
"token_type": {
"type": "string",
"example": "bearer"
},
"expires_in": {
"type": "number",
"example": 7200
},
"refresh_token": {
"type": "string",
"example": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1"
},
"scope": {
"type": "array",
"example": [
"api",
"create_runner",
"read_repository",
"write_repository"
],
"items": {
"type": "string"
}
},
"created_at": {
"type": "number",
"example": 1607635748
}
},
"required": [
"access_token",
"token_type",
"expires_in",
"refresh_token",
"scope",
"created_at"
]
}
}
}
]
}
}
}
}
*/
try {
const params: {
refreshToken: string
......@@ -202,21 +73,6 @@ class SessionRoutes implements RoutesManager {
}
private async testSession(req: express.Request, res: express.Response) {
/*
#swagger.tags = ['Session']
#swagger.summary = 'Test of the session'
#swagger.description = 'This route can be used to test the validity of the session token.'
#swagger.responses[200] = {
content: {
"application/json": {
schema:{
$ref: "#/components/schemas/DojoBackendResponse"
}
}
}
}
*/
req.session.sendResponse(res, StatusCodes.OK);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment