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

OpenAPI => Add manual documentation

parent 5b88f058
No related branches found
No related tags found
No related merge requests found
Pipeline #27132 passed
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SwaggerSettings">
<option name="defaultPreviewType" value="SWAGGER_UI" />
</component>
</project>
\ No newline at end of file
openapi: 3.1.0
info:
title: Dojo API
version: 3.1.0
description: |
**Backend API of the Dojo project.**
See more information about the projet on
[Gitlab](https://githepia.hesge.ch/dojo_project/dojo).
license:
name: AGPLv3
identifier: AGPL-3.0-only
contact:
name: Michaël Minelli
email: dojo@minelli.me
servers:
- url: http://localhost:30993/
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
paths:
/health_check:
get:
tags:
- General
summary: Health check
description: This route can be used to check if the server is up and running.
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/DojoBackendResponse'
description: OK
default:
$ref: '#/components/responses/ERROR'
/login:
post:
tags:
- Session
summary: Login to Dojo app
description: |
This route can be used to connect the user to the backend and retrieve
informations about his access rights.
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
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
type: object
nullable: true
'404':
$ref: '#/components/responses/NOT_FOUND'
default:
$ref: '#/components/responses/ERROR'
/refresh_tokens:
post:
tags:
- Session
summary: Refresh tokens
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.
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
refreshToken:
type: string
format: Gitlab refresh token
required:
- refreshToken
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
examples:
- de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54
token_type:
type: string
examples:
- bearer
expires_in:
type: number
examples:
- 7200
refresh_token:
type: string
examples:
- 8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1
scope:
type: array
examples:
- - api
- create_runner
- read_repository
- write_repository
items:
type: string
created_at:
type: number
examples:
- 1607635748
required:
- access_token
- token_type
- expires_in
- refresh_token
- scope
- created_at
default:
$ref: '#/components/responses/ERROR'
/test_session:
get:
tags:
- Session
summary: Test of the session
description: This route can be used to test the validity of the session token.
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/DojoBackendResponse'
default:
$ref: '#/components/responses/ERROR'
/gitlab/project/{gitlabProjectIdOrNamespace}/checkTemplateAccess:
get:
tags:
- Gitlab
summary: Check access to template repository
description: |
This route can be used to check if the template repository is accessible by the Dojo user.
**🔒 Security needs:** any access rights
security:
- Clients_Token: [ ]
parameters:
- $ref: '#/components/parameters/gitlabProjectIdOrNamespace'
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
type: object
nullable: true
'401':
$ref: '#/components/responses/UNAUTHORIZED'
'404':
$ref: '#/components/responses/NOT_FOUND'
default:
$ref: '#/components/responses/ERROR'
/assignments/{assignmentNameOrUrl}:
get:
tags:
- Assignment
summary: Get an assignment
description: |
This route can be used to get an assignment's informations by its name or its url.
If it's not published and the user is not a member of the staff (or admin), some informations will not be provided.
Informations that will be deleted:
- gitlabId
- gitlabLink
- gitlabCreationInfo
- gitlabLastInfo
- gitlabLastInfoDate
- staff
- exercises
**🔒 Security needs:** any access rights
security:
- Clients_Token: [ ]
parameters:
- $ref: '#/components/parameters/assignmentNameOrUrl'
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Assignment'
'401':
$ref: '#/components/responses/UNAUTHORIZED'
'404':
$ref: '#/components/responses/NOT_FOUND'
default:
$ref: '#/components/responses/ERROR'
/assignments:
post:
tags:
- Assignment
summary: Create a new assignment
description: |
**🔒 Security needs:** TeachingStaff or Admin roles
security:
- Clients_Token: [ ]
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
name:
type: string
description: Name of the assignment (must be unique)
members:
type: string
format: json
description: JSON string of an array of gitlab user objects
externalDocs:
description: Gitlab user object
url: https://docs.gitlab.com/ee/api/users.html#list-users
template:
type: string
format: url
description: URL of the template to use as base of the assignment
required:
- name
- members
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Assignment'
'401':
$ref: '#/components/responses/UNAUTHORIZED'
default:
$ref: '#/components/responses/ERROR'
/assignments/{assignmentNameOrUrl}/publish:
patch:
tags:
- Assignment
summary: Publish an assignment
description: |
**🔒 Security needs:** TeachingStaff of the assignment or Admin role
security:
- Clients_Token: [ ]
parameters:
- $ref: '#/components/parameters/assignmentNameOrUrl'
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
type: object
nullable: true
'401':
$ref: '#/components/responses/UNAUTHORIZED'
'404':
$ref: '#/components/responses/NOT_FOUND'
default:
$ref: '#/components/responses/ERROR'
/assignments/{assignmentNameOrUrl}/unpublish:
patch:
tags:
- Assignment
summary: Unpublish an assignment
description: |
**🔒 Security needs:** TeachingStaff of the assignment or Admin role
security:
- Clients_Token: [ ]
parameters:
- $ref: '#/components/parameters/assignmentNameOrUrl'
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
type: object
nullable: true
'401':
$ref: '#/components/responses/UNAUTHORIZED'
'404':
$ref: '#/components/responses/NOT_FOUND'
default:
$ref: '#/components/responses/ERROR'
/assignments/{assignmentNameOrUrl}/exercises:
post:
tags:
- Exercise
summary: Create a new exercise
description: |
This route can be used to create a new exercise based on an assignment.
**🔒 Security needs:** The assignment must be published
security:
- Clients_Token: [ ]
parameters:
- $ref: '#/components/parameters/assignmentNameOrUrl'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
members:
type: string
format: json
description: JSON string of an array of gitlab user objects
externalDocs:
description: Gitlab user object
url: https://docs.gitlab.com/ee/api/users.html#list-users
required:
- members
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Exercise'
'401':
$ref: '#/components/responses/UNAUTHORIZED'
'404':
$ref: '#/components/responses/NOT_FOUND'
'419':
description: |
At least one of the members of the exercices have reached the maximum number of exercises for this assignment.
Users that have reached the maximum number of exercises are listed in the `data` field.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
default:
$ref: '#/components/responses/ERROR'
/exercises/{exerciseId}/assignment:
get:
tags:
- Exercise
- Assignment
summary: Get the assignment of an exercise
security:
- ExerciseChecker_Secret: [ ]
parameters:
- $ref: '#/components/parameters/exerciseId'
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
type: object
properties:
assignment:
$ref: '#/components/schemas/Assignment'
assignmentFile:
$ref: '#/components/schemas/AssignmentFile'
immutable:
type: array
items:
type: object
description: Gitlab file object
externalDocs:
description: Gitlab file object
url: https://docs.gitlab.com/ee/api/repository_files.html#get-file-from-repository
'401':
$ref: '#/components/responses/UNAUTHORIZED'
'404':
$ref: '#/components/responses/NOT_FOUND'
default:
$ref: '#/components/responses/ERROR'
/exercises/{exerciseId}/results:
post:
tags:
- Exercise
summary: Get results of an exercise
security:
- ExerciseChecker_Secret: [ ]
parameters:
- $ref: '#/components/parameters/exerciseId'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
exitCode:
type: number
description: The exit code of the exercise execution
commit:
type: string
format: json
description: JSON string of an array of gitlab user objects
externalDocs:
description: Gitlab commit object
url: https://docs.gitlab.com/ee/api/commits.html#get-a-single-commit
results:
type: string
format: json
description: JSON string of a DojoResult object (see in schemas)
externalDocs:
description: DojoResult object
url: '#/components/schemas/DojoResult'
files:
type: string
format: json
description: JSON string of an array of file objects
archiveBase64:
type: string
format: base64
description: Base64 encoded archive of the exercise's results
required:
- exitCode
- commit
- results
- files
- archiveBase64
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DojoBackendResponse'
- type: object
properties:
data:
type: object
nullable: true
'401':
$ref: '#/components/responses/UNAUTHORIZED'
'404':
$ref: '#/components/responses/NOT_FOUND'
default:
$ref: '#/components/responses/ERROR'
components:
securitySchemes:
Clients_Token:
type: http
scheme: bearer
bearerFormat: JWT
ExerciseChecker_Secret:
type: apiKey
in: header
name: ExerciseSecret
parameters:
gitlabProjectIdOrNamespace:
name: gitlabProjectIdOrNamespace
description: |
The id or the namespace of the project. The namespace is the
path of the project (e.g. `dojo_project/dojo`).
in: path
required: true
schema:
type: string
assignmentNameOrUrl:
name: assignmentNameOrUrl
description: The name or the url of an assignment.
in: path
required: true
schema:
type: string
exerciseId:
name: exerciseId
description: The id of an exercise.
in: path
required: true
schema:
type: string
format: uuidv4
schemas:
DojoBackendResponse:
type: object
properties:
timestamp:
type: string
examples:
- '1992-09-30T19:00:00.000Z'
code:
type: number
examples:
- 200
description:
type: string
examples:
- OK
sessionToken:
type: string
examples:
- JWT token (for content, see schema named 'SessionTokenJWT')
data:
type: object
properties: { }
required:
- timestamp
- code
- description
- sessionToken
- data
User:
type: object
properties:
id:
type: number
examples:
- 142
name:
type: string
examples:
- michael.minelli
mail:
type: string
examples:
- dojo@minelli.me
role:
type: string
enum:
- STUDENT
- TEACHING_STAFF
- ADMIN
gitlabUsername:
type: string
examples:
- michael.minelli
gitlabLastInfo:
type: object
properties: { }
externalDocs:
description: Gitlab user object
url: https://docs.gitlab.com/ee/api/users.html#list-users
isTeachingStaff:
type: boolean
examples:
- true
isAdmin:
type: boolean
examples:
- true
deleted:
type: boolean
examples:
- false
assignments:
type: array
items:
$ref: '#/components/schemas/Assignment'
exercises:
type: array
items:
$ref: '#/components/schemas/Exercise'
required:
- id
- role
- gitlabUsername
- isTeachingStaff
- isAdmin
- deleted
Assignment:
type: object
properties:
name:
type: string
examples:
- C_Hello_World
gitlabId:
type: number
examples:
- 30992
gitlabLink:
type: string
examples:
- https://githepia.hesge.ch/dojo_project
gitlabCreationInfo:
type: object
properties: { }
externalDocs:
description: Gitlab project object
url: https://docs.gitlab.com/ee/api/projects.html#get-single-project
gitlabLastInfo:
type: object
properties: { }
externalDocs:
description: Gitlab project object
url: https://docs.gitlab.com/ee/api/projects.html#get-single-project
gitlabLastInfoDate:
type: string
examples:
- '1992-09-30 19:00:00.000'
published:
type: boolean
examples:
- true
staff:
type: array
items:
$ref: '#/components/schemas/User'
exercises:
type: array
items:
$ref: '#/components/schemas/Exercise'
required:
- name
- gitlabId
- gitlabLink
- gitlabCreationInfo
- gitlabLastInfo
- gitlabLastInfoDate
- published
- staff
- exercises
Exercise:
type: object
properties:
id:
type: string
format: uuidv4
examples:
- eb5f2182-f5b1-42a9-80fc-cad384571053
assignmentName:
type: string
examples:
- C_Hello_World
name:
type: string
examples:
- DojoEx - C_Hello_World - michael.minelli
gitlabId:
type: number
examples:
- 93092
gitlabLink:
type: string
examples:
- https://githepia.hesge.ch/dojo_project/dojo
gitlabCreationInfo:
type: object
properties: { }
externalDocs:
description: Gitlab project object
url: https://docs.gitlab.com/ee/api/projects.html#get-single-project
gitlabLastInfo:
type: object
properties: { }
externalDocs:
description: Gitlab project object
url: https://docs.gitlab.com/ee/api/projects.html#get-single-project
gitlabLastInfoDate:
type: string
examples:
- '1992-09-30 19:00:00.000'
required:
- id
- assignmentName
- name
- gitlabId
- gitlabLink
- gitlabCreationInfo
- gitlabLastInfo
- gitlabLastInfoDate
DojoResult:
type: object
properties:
success:
type: boolean
examples:
- true
containerExitCode:
type: number
examples:
- 0
successfulTests:
type: number
examples:
- 3
failedTests:
type: number
examples:
- 0
successfulTestsList:
type: array
items:
type: string
examples:
- [ "Test 1", "Test 2", "Test 3" ]
failedTestsList:
type: array
items:
type: string
examples:
- [ ]
required:
- success
- containerExitCode
AssignmentFile:
type: object
properties:
dojoAssignmentVersion:
type: number
examples:
- 1
version:
type: number
examples:
- 1
immutable:
type: array
items:
type: object
properties:
description:
type: string
examples:
- Dockerfile of the unique container
path:
type: string
examples:
- Dockerfile
isDirectory:
type: boolean
examples:
- false
required:
- path
result:
type: object
properties:
container:
type: string
examples:
- hello_world
volume:
type: string
examples:
- hello_world_volume
required:
- container
required:
- dojoAssignmentVersion
- version
- immutable
- result
SessionTokenJWT:
type: object
properties:
profile:
$ref: '#/components/schemas/User'
iat:
type: string
examples:
- '1700749215'
required:
- profile
- iat
examples:
DojoBackendResponseERROR:
value:
timestamp: '1992-09-30T19:00:00.000Z'
code: 500
description: ERROR_MESSAGE
sessionToken: JWT token (for content, see schema named 'SessionTokenJWT')
data: null
responses:
UNAUTHORIZED:
description: UNAUTHORIZED
content:
application/json:
schema:
$ref: '#/components/schemas/DojoBackendResponse'
example:
timestamp: '1992-09-30T19:00:00.000Z'
code: 401
description: UNAUTHORIZED
sessionToken: JWT token (for content, see schema named 'SessionTokenJWT')
data: null
NOT_FOUND:
description: NOT FOUND
content:
application/json:
schema:
$ref: '#/components/schemas/DojoBackendResponse'
example:
timestamp: '1992-09-30T19:00:00.000Z'
code: 404
description: NOT_FOUND
sessionToken: JWT token (for content, see schema named 'SessionTokenJWT')
data: null
ERROR:
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/DojoBackendResponse'
example:
timestamp: '1992-09-30T19:00:00.000Z'
code: 5XX or Internal code
description: This is an error message
sessionToken: JWT token (for content, see schema named 'SessionTokenJWT')
data: null
\ No newline at end of file
......@@ -48,12 +48,12 @@ class API implements WorkerTask {
private initSwagger() {
const options = {
swaggerOptions: {
url: '/docs/openapi.json'
url: '/docs/OpenAPI.yaml'
}
};
this.backend.get('/docs/openapi.json', (req, res) => res.sendFile(path.resolve(__dirname + '/../../assets/openapi.json')));
this.backend.get('/docs/OpenAPI.yaml', (req, res) => res.sendFile(path.resolve(__dirname + '/../../assets/OpenAPI/OpenAPI.yaml')));
this.backend.use('/docs/swagger', swaggerUi.serveFiles(undefined, options), swaggerUi.setup(undefined, options));
this.backend.get('/docs/redoc.html', (req, res) => res.sendFile(path.resolve(__dirname + '/../../assets/redoc.html')));
this.backend.get('/docs/redoc.html', (req, res) => res.sendFile(path.resolve(__dirname + '/../../assets/OpenAPI/redoc.html')));
this.backend.get('/docs/', (req, res) => {
res.send(`
......@@ -61,7 +61,7 @@ class API implements WorkerTask {
<html lang="en">
<body>
<ul>
<li><a href="/docs/openapi.json">OpenAPI</a></li>
<li><a href="/docs/OpenAPI.yaml">OpenAPI</a></li>
<li>GUI
<ul>
<li><a href="/docs/swagger">Swagger</a></li>
......
......@@ -56,8 +56,8 @@ class GitlabManager {
}
}
async getRepository(idOrNamespace: string): Promise<GitlabRepository> {
const response = await axios.get<GitlabRepository>(this.getApiUrl(GitlabRoute.REPOSITORY_GET).replace('{{id}}', encodeURIComponent(idOrNamespace)));
async getRepository(projectIdOrNamespace: string): Promise<GitlabRepository> {
const response = await axios.get<GitlabRepository>(this.getApiUrl(GitlabRoute.REPOSITORY_GET).replace('{{id}}', encodeURIComponent(projectIdOrNamespace)));
return response.data;
}
......@@ -140,10 +140,10 @@ class GitlabManager {
return response.data;
}
async checkTemplateAccess(idOrNamespace: string, req: express.Request): Promise<StatusCodes> {
async checkTemplateAccess(projectIdOrNamespace: string, req: express.Request): Promise<StatusCodes> {
// Get the Gitlab project and check if it have public or internal visibility
try {
const project: GitlabRepository = await this.getRepository(idOrNamespace);
const project: GitlabRepository = await this.getRepository(projectIdOrNamespace);
if ( [ GitlabVisibility.PUBLIC.valueOf(), GitlabVisibility.INTERNAL.valueOf() ].includes(project.visibility) ) {
return StatusCodes.OK;
......@@ -153,7 +153,7 @@ class GitlabManager {
}
// Check if the user and dojo are members (with at least reporter access) of the project
const members = await this.getRepositoryMembers(idOrNamespace);
const members = await this.getRepositoryMembers(projectIdOrNamespace);
const isUsersAtLeastReporter = {
user: false,
dojo: false
......
......@@ -8,15 +8,13 @@ import GitlabManager from '../managers/GitlabManager';
class GitlabRoutes implements RoutesManager {
registerOnBackend(backend: Express) {
backend.get('/gitlab/project/:idOrNamespace/checkTemplateAccess', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), this.checkTemplateAccess);
backend.get('/gitlab/project/:gitlabProjectIdOrNamespace/checkTemplateAccess', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), this.checkTemplateAccess);
}
private async checkTemplateAccess(req: express.Request, res: express.Response) {
const gitlabProjectIdOrNamespace: string = req.params.gitlabProjectIdOrNamespace;
const idOrNamespace: string = req.params.idOrNamespace;
return res.status(await GitlabManager.checkTemplateAccess(idOrNamespace, req)).send();
return res.status(await GitlabManager.checkTemplateAccess(gitlabProjectIdOrNamespace, req)).send();
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment