diff --git a/openapi.yml b/openapi.yml index 0d4399d..194d5df 100644 --- a/openapi.yml +++ b/openapi.yml @@ -3,20 +3,72 @@ info: title: CodeCombat API version: '' paths: - /auth/login-o-auth: + users/{handle}/o-auth-identities: + post: + description: > + Adds an OAuth2 identity to the user, so that they can be logged in with + that identity. You need to send the OAuth code or the access token to + this endpoint. 1. If no access token is provided, it will use your + OAuth2 token URL to exchange the given code for an access token. 2. Then + it will use the access token (given by you, or received from step 1) to + look up the user on your service using the lookup URL, and expects a + JSON object in response with an `id` property. 3. It will then save that + user `id` to the user in our db as a new OAuthIdentity. In this example, + we call your lookup URL (let's say, `https://oauth.provider/user?t=<%= + accessToken %>`) with the access token (`1234`). The lookup URL returns + `{ id: 'abcd' }` in this case, which we save to the user in our db. + operationId: Service.postUsersHandleOAuthIdentities + tags: + - '' + parameters: + - name: handle + in: path + description: The document's `_id` or `slug`. + required: true + schema: + type: string + responses: + '200': + description: The affected user + content: + application/json: + schema: + $ref: '#/components/schemas/UserResponse' + summary: Add Oauth2 Identity + security: &ref_0 + - BasicAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + provider: + type: string + description: Your OAuth Provider ID. + accessToken: + type: string + description: >- + Will be passed through your lookup URL to get the user ID. + Required if no `code`. + code: + type: string + description: >- + Will be passed to the OAuth token endpoint to get a token. + Required if no `accessToken`. + required: + - provider + auth/login-o-auth: get: description: > - Logs a [user](#users) in. #### Example ```javascript url = - `https://codecombat.com/auth/login-o-auth?provider=${OAUTH_PROVIDER_ID}&accessToken=1234` - res.redirect(url) // User is sent to this CodeCombat URL and assuming - everything checks out, // is logged in and redirected to the home page. - ``` In this example, we call your lookup URL (let's say, + Logs a user in. In this example, we call your lookup URL (let's say, `https://oauth.provider/user?t=<%= accessToken %>`) with the access token (`1234`). The lookup URL returns `{ id: 'abcd' }` in this case. We will match this `id` with the OAuthIdentity stored in the user information in our db. If everything checks out, the user is logged in and redirected to the home page. - operationId: AuthService.get + operationId: AuthService.loginOauth tags: - Auth parameters: @@ -62,12 +114,11 @@ paths: '204': description: '' summary: Login User - security: &ref_0 - - BasicAuth: [] - /clan/{handle}/members: + security: *ref_0 + clan/{handle}/members: put: description: Upserts a user into the clan. - operationId: ClansService.upsertClan + operationId: ClansService.upsertMember tags: - Clans parameters: @@ -79,7 +130,7 @@ paths: type: string responses: '200': - description: '' + description: The clan with the member added. content: application/json: schema: @@ -98,7 +149,7 @@ paths: description: The `_id` or `slug` of the user to add to the clan. required: - userId - /classrooms: + classrooms: get: description: Returns the classroom details for a class code. operationId: ClassroomsService.get @@ -120,7 +171,7 @@ paths: format: double responses: '200': - description: '' + description: The classroom details. content: application/json: schema: @@ -134,9 +185,13 @@ paths: - Classrooms parameters: [] responses: - '204': - description: '' - summary: Create a Classroom + '200': + description: The created classroom + content: + application/json: + schema: + $ref: '#/components/schemas/ClassroomResponseWithCode' + summary: Create a classroom security: *ref_0 requestBody: required: true @@ -151,15 +206,15 @@ paths: ownerID: $ref: '#/components/schemas/objectIdString' aceConfig: - $ref: '#/components/schemas/AceConfig' + $ref: '#/components/schemas/ClassroomsCreateRequestAceConfig' required: - name - ownerID - aceConfig - /classrooms/{handle}/members: + classrooms/{handle}/members: put: description: Upserts a user into the classroom. - operationId: ClassroomsService.upsertFromClassroom + operationId: ClassroomsService.upsertMember tags: - Classrooms parameters: @@ -171,12 +226,12 @@ paths: type: string responses: '200': - description: '' + description: The classroom with the member added. content: application/json: schema: $ref: '#/components/schemas/ClassroomResponse' - summary: Upsert a User from Classroom + summary: Upsert a user from classroom security: *ref_0 requestBody: required: true @@ -202,7 +257,7 @@ paths: - userId delete: description: Remove a user from the classroom. - operationId: ClassroomsService.deleteUserFromClassroom + operationId: ClassroomsService.removeMember tags: - Classrooms parameters: @@ -214,7 +269,7 @@ paths: type: string responses: '200': - description: '' + description: The classroom with the member removed. content: application/json: schema: @@ -239,7 +294,7 @@ paths: default value is 1000 required: - userId - /classrooms/{classroomHandle}/courses/{courseHandle}/enrolled: + classrooms/{classroomHandle}/courses/{courseHandle}/enrolled: put: description: | Enrolls a user in a course in a classroom. @@ -272,12 +327,12 @@ paths: format: double responses: '200': - description: '' + description: The classroom with the user enrolled. content: application/json: schema: $ref: '#/components/schemas/ClassroomResponse' - summary: Enroll a User in a Course + summary: Enroll User in a Course security: *ref_0 requestBody: required: true @@ -290,11 +345,11 @@ paths: $ref: '#/components/schemas/objectIdString' required: - userId - /classrooms/{classroomHandle}/courses/{courseHandle}/remove-enrolled: + classrooms/{classroomHandle}/courses/{courseHandle}/remove-enrolled: put: description: | Removes an enrolled user from a course in a classroom. - operationId: ClassroomsService.removeUserFromClassroom + operationId: ClassroomsService.removeEnrolledUser tags: - Classrooms parameters: @@ -321,12 +376,12 @@ paths: format: double responses: '200': - description: '' + description: The classroom with the user removed from the course. content: application/json: schema: $ref: '#/components/schemas/ClassroomResponse' - summary: Remove a User from a Classroom + summary: Remove User from a classroom security: *ref_0 requestBody: required: true @@ -339,7 +394,7 @@ paths: $ref: '#/components/schemas/objectIdString' required: - userId - /classrooms/{classroomHandle}/stats: + classrooms/{classroomHandle}/stats: get: description: | Returns a list of all members stats for the classroom. @@ -381,20 +436,20 @@ paths: format: double responses: '200': - description: '' + description: The members stats for the classroom. content: application/json: schema: type: array items: - $ref: '#/components/schemas/MemberStat' - summary: Get Members Stats for a Classroom + $ref: '#/components/schemas/ClassroomsGetMembersStatsResponseItem' + summary: Get Member Stats security: *ref_0 - /classrooms/{classroomHandle}/members/{memberHandle}/sessions: + classrooms/{classroomHandle}/members/{memberHandle}/sessions: get: description: | Returns a list of all levels played by the user for the classroom. - operationId: ClassroomsService.getLevelSession + operationId: ClassroomsService.getLevelsPlayed tags: - Classrooms parameters: @@ -412,7 +467,7 @@ paths: type: string responses: '200': - description: '' + description: The classroom with the user enrolled. content: application/json: schema: @@ -421,7 +476,7 @@ paths: $ref: '#/components/schemas/LevelSessionResponse' summary: Get Level Session security: *ref_0 - /playtime-stats: + playtime-stats: get: description: Returns the playtime stats operationId: StatsService.getPlaytimeStats @@ -448,14 +503,14 @@ paths: type: string responses: '200': - description: '' + description: Returns the playtime stats accross all owned users. content: application/json: schema: $ref: '#/components/schemas/PlaytimeStatsResponse' summary: Get Playtime Stats security: *ref_0 - /license-stats: + license-stats: get: description: Returns the license stats operationId: StatsService.getLicenseStats @@ -464,30 +519,28 @@ paths: parameters: [] responses: '200': - description: '' + description: Returns the license stats for classroom/home subscription licenses. content: application/json: schema: $ref: '#/components/schemas/LicenseStatsResponse' summary: Get License Stats security: *ref_0 - /users: + users: post: description: | Creates a `User`. - #### Example - ```javascript - url = 'https://codecombat.com/api/users' - json = { email: 'an@email.com', name: 'Some Username', role: 'student' } - request.post({ url, json, auth }) - ``` operationId: UsersService.create tags: - Users parameters: [] responses: - '204': - description: '' + '200': + description: The created user + content: + application/json: + schema: + $ref: '#/components/schemas/UserResponse' summary: Create User security: *ref_0 requestBody: @@ -502,20 +555,20 @@ paths: email: type: string role: - $ref: '#/components/schemas/UserRole' - description: >- - A `"student"` or `"teacher"`. If unset, a home user will be + $ref: '#/components/schemas/UsersCreateRequestRole' + description: > + `"student"` or `"teacher"`. If unset, a home user will be created, unable to join classrooms. preferredLanguage: type: string heroConfig: - $ref: '#/components/schemas/HeroConfig' + $ref: '#/components/schemas/UsersCreateRequestHeroConfig' birthday: type: string required: - name - email - /users/{handle}: + users/{handle}: get: description: Returns a `User`. operationId: UsersService.get @@ -536,7 +589,7 @@ paths: type: string responses: '200': - description: '' + description: The requested user content: application/json: schema: @@ -557,7 +610,7 @@ paths: type: string responses: '200': - description: '' + description: The affected user content: application/json: schema: @@ -579,7 +632,7 @@ paths: description: Set the birthday required: - name - /users/{handle}/classrooms: + users/{handle}/classrooms: get: description: >- Returns a list of `Classrooms` this user is in (if a student) or owns @@ -603,7 +656,7 @@ paths: format: double responses: '200': - description: '' + description: The requested classrooms content: application/json: schema: @@ -612,10 +665,10 @@ paths: $ref: '#/components/schemas/ClassroomResponseWithCode' summary: Get Classrooms By User security: *ref_0 - /users/{handle}/hero-config: + users/{handle}/hero-config: put: description: Set the user's hero. - operationId: UsersService.getHero + operationId: UsersService.setHero tags: - Users parameters: @@ -627,7 +680,7 @@ paths: type: string responses: '200': - description: '' + description: The affected user content: application/json: schema: @@ -643,7 +696,7 @@ paths: properties: thangType: $ref: '#/components/schemas/objectIdString' - /users/{handle}/ace-config: + users/{handle}/ace-config: put: description: >- Set the user's aceConfig (the settings for the in-game Ace code editor), @@ -660,11 +713,12 @@ paths: type: string responses: '200': - description: '' + description: The affected user content: application/json: schema: $ref: '#/components/schemas/UserResponse' + summary: Put Ace Config security: *ref_0 requestBody: required: true @@ -688,80 +742,11 @@ paths: description: >- only for home users, should be one of ["python", "javascript", "cpp", "lua", "coffeescript"] right now - /users/{handle}/o-auth-identities: - post: - description: > - Adds an OAuth2 identity to the user, so that they can be logged in with - that identity. You need to send the OAuth code or the access token to - this endpoint. 1. If no access token is provided, it will use your - OAuth2 token URL to exchange the given code for an access token. 1. Then - it will use the access token (given by you, or received from step 1) to - look up the user on your service using the lookup URL, and expects a - JSON object in response with an `id` property. 1. It will then save that - user `id` to the user in our db as a new OAuthIdentity. #### Example - ```javascript url = - `https://codecombat.com/api/users/${userID}/o-auth-identities` - OAUTH_PROVIDER_ID = 'xyz' json = { provider: OAUTH_PROVIDER_ID, - accessToken: '1234' } request.post({ url, json, auth}, (err, res) => { - console.log(res.body.oAuthIdentities) // [ { provider: 'xyx', id: 'abcd' } ] - }) ``` In this example, we call your lookup URL (let's say, - `https://oauth.provider/user?t=<%= accessToken %>`) with the access - token (`1234`). The lookup URL returns `{ id: 'abcd' }` in this case, - which we save to the user in our db. - operationId: UsersService.addOAuthIdentity - tags: - - Users - parameters: - - name: handle - in: path - description: The document's `_id` or `slug`. - required: true - schema: - type: string - responses: - '200': - description: '' - content: - application/json: - schema: - $ref: '#/components/schemas/UserResponse' - summary: Add OAuth2 Identity - security: *ref_0 - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - provider: - type: string - description: Your OAuth Provider ID. - accessToken: - type: string - description: >- - Will be passed through your lookup URL to get the user ID. - Required if no `code`. - code: - type: string - description: >- - Will be passed to the OAuth token endpoint to get a token. - Required if no `accessToken`. - required: - - provider - /users/{handle}/subscription: + users/{handle}/subscription: put: description: | Grants a user premium access to the "Home" version up to a certain time. - #### Example - ```javascript - url = `https://codecombat.com/api/users/${userID}/subscription` - json = { ends: new Date('2017-01-01').toISOString() } - request.put({ url, json, auth }, (err, res) => { - console.log(res.body.subscription) // { ends: '2017-01-01T00:00:00.000Z', active: true } - }) - ``` - operationId: UsersService.updateSubscription + operationId: UsersService.grantPremiumSubscription tags: - Users parameters: @@ -773,11 +758,12 @@ paths: type: string responses: '200': - description: '' + description: The affected user content: application/json: schema: $ref: '#/components/schemas/UserResponse' + summary: Put Subscription security: *ref_0 requestBody: required: true @@ -787,23 +773,16 @@ paths: type: object properties: ends: - type: string - format: date-time + $ref: '#/components/schemas/datetimeString' required: - ends - /users/{handle}/shorten-subscription: + users/{handle}/shorten-subscription: put: description: > If the user already has a premium access up to a certain time, this shortens/revokes his/her premium access. If the ends is less than or equal to the current time, it revokes the subscription and sets the end date to be the current time, else it just shortens the subscription. - #### Example ```javascript url = - `https://codecombat.com/api/users/${userID}/shorten-subscription` json = - { ends: new Date().toISOString() } request.put({ url, json, auth }, - (err, res) => { - console.log(res.body.subscription.active) // false - }) ``` operationId: UsersService.shortenSubscription tags: - Users @@ -816,7 +795,7 @@ paths: type: string responses: '200': - description: '' + description: The affected user content: application/json: schema: @@ -831,23 +810,14 @@ paths: type: object properties: ends: - type: string - format: date-time + $ref: '#/components/schemas/datetimeString' required: - ends - /users/{handle}/license: + users/{handle}/license: put: description: | Grants a user access to the "Classroom" version up to a certain time. Sets their role to "student". - #### Example - ```javascript - url = `https://codecombat.com/api/users/${userID}/license` - json = { ends: new Date('2017-01-01').toISOString() } - request.put({ url, json, auth }, (err, res) => { - console.log(res.body.license) // { ends: '2017-01-01T00:00:00.000Z', active: true } - }) - ``` operationId: UsersService.grantLicense tags: - Users @@ -860,7 +830,7 @@ paths: type: string responses: '200': - description: '' + description: The affected user content: application/json: schema: @@ -875,23 +845,17 @@ paths: type: object properties: ends: - type: string - format: date-time + $ref: '#/components/schemas/datetimeString' required: - ends - /users/{handle}/shorten-license: + users/{handle}/shorten-license: put: description: > If the user already has access to the "Classroom" version up to a certain time, this shortens/revokes his/her access. If the ends is less than or equal to the current time, it revokes the enrollment and sets the end date to be the current time, else it just shortens the - enrollment. #### Example ```javascript url = - `https://codecombat.com/api/users/${userID}/shorten-license` json = { - ends: new Date().toISOString() } request.put({ url, json, auth }, (err, - res) => { - console.log(res.body.license.active) // false - }) ``` + enrollment. operationId: UsersService.shortenLicense tags: - Users @@ -904,7 +868,7 @@ paths: type: string responses: '200': - description: '' + description: The affected user content: application/json: schema: @@ -919,14 +883,13 @@ paths: type: object properties: ends: - type: string - format: date-time + $ref: '#/components/schemas/datetimeString' required: - ends - /user-lookup/{property}/{value}: + user-lookup/{property}/{value}: get: description: Redirects to `/users/{handle}` given a unique, identifying property - operationId: UsersService.findUser + operationId: UsersService.lookup tags: - Users parameters: @@ -949,78 +912,33 @@ paths: security: *ref_0 components: schemas: - ClanResponse: - type: object - description: Subset of properties listed here - properties: - _id: - $ref: '#/components/schemas/objectIdString' - name: - type: string - displayName: - type: string - members: - type: array - items: - $ref: '#/components/schemas/objectIdString' - ownerID: - $ref: '#/components/schemas/objectIdString' - description: - type: string - type: - type: string - kind: - type: string - metadata: - type: object - additionalProperties: {} - LevelSessionResponse: + UsersCreateRequestRole: + type: string + enum: + - student + - teacher + description: > + `"student"` or `"teacher"`. If unset, a home user will be created, + unable to join classrooms. + UsersCreateRequestHeroConfig: type: object properties: - state: - $ref: '#/components/schemas/State' - level: - $ref: '#/components/schemas/Level' - levelID: - type: string - description: Level slug like `wakka-maul` - creator: + thangType: $ref: '#/components/schemas/objectIdString' - playtime: - type: integer - description: Time played in seconds. - changed: - $ref: '#/components/schemas/datetimeString' - created: - $ref: '#/components/schemas/datetimeString' - dateFirstCompleted: - $ref: '#/components/schemas/datetimeString' - submitted: - type: boolean - description: For arenas. Whether or not the level has been added to the ladder. - published: - type: boolean - description: >- - For shareable projects. Whether or not the project has been shared - with classmates. - State: - type: object - properties: - complete: - type: boolean - Level: - type: object - properties: - original: - type: string - description: The id for the level. - AceConfig: + ClassroomsCreateRequestAceConfig: type: object properties: language: type: string description: Programming language for the classroom - PlayStats: + ClassroomsGetMembersStatsResponseItem: + type: object + properties: + _id: + $ref: '#/components/schemas/objectIdString' + stats: + $ref: '#/components/schemas/ClassroomsGetMembersStatsResponseItemStats' + ClassroomsGetMembersStatsResponseItemStats: type: object properties: gamesCompleted: @@ -1030,13 +948,13 @@ components: type: number format: double description: Total play time in seconds - MemberStat: - type: object - properties: - _id: - $ref: '#/components/schemas/objectIdString' - stats: - $ref: '#/components/schemas/PlayStats' + roleString: + type: string + description: Usually either 'teacher' or 'student' + datetimeString: + type: string + objectIdString: + type: string UserResponse: type: object description: Subset of properties listed here @@ -1052,16 +970,16 @@ components: role: $ref: '#/components/schemas/roleString' stats: - $ref: '#/components/schemas/UserStats' + $ref: '#/components/schemas/UserResponseStats' oAuthIdentities: type: array items: - $ref: '#/components/schemas/AuthIdentity' + $ref: '#/components/schemas/UserResponseOAuthIdentitiesItem' subscription: - $ref: '#/components/schemas/Subscription' + $ref: '#/components/schemas/UserResponseSubscription' license: - $ref: '#/components/schemas/License' - UserStats: + $ref: '#/components/schemas/UserResponseLicense' + UserResponseStats: type: object properties: gamesCompleted: @@ -1076,35 +994,28 @@ components: type: number format: double description: Included only when specifically requested on the endpoint - AuthIdentity: + UserResponseOAuthIdentitiesItem: type: object properties: provider: type: string id: type: string - Subscription: + UserResponseSubscription: type: object properties: ends: $ref: '#/components/schemas/datetimeString' active: type: boolean - License: + UserResponseLicense: type: object properties: ends: $ref: '#/components/schemas/datetimeString' active: type: boolean - objectIdString: - type: string - roleString: - type: string - description: Usually either 'teacher' or 'student' - datetimeString: - type: string - ClassroomResponseWithCode: + ClassroomResponse: type: object description: Subset of properties listed here properties: @@ -1120,17 +1031,11 @@ components: $ref: '#/components/schemas/objectIdString' description: type: string - code: - type: string - codeCamel: - type: string courses: type: array items: - $ref: '#/components/schemas/Course' - clanId: - $ref: '#/components/schemas/objectIdString' - Course: + $ref: '#/components/schemas/ClassroomResponseCoursesItem' + ClassroomResponseCoursesItem: type: object properties: _id: @@ -1146,7 +1051,7 @@ components: $ref: '#/components/schemas/objectIdString' instance_id: $ref: '#/components/schemas/objectIdString' - ClassroomResponse: + ClassroomResponseWithCode: type: object description: Subset of properties listed here properties: @@ -1154,21 +1059,40 @@ components: $ref: '#/components/schemas/objectIdString' name: type: string - description: The name of the classroom members: type: array items: $ref: '#/components/schemas/objectIdString' - description: List of _ids of the student members of the classroom ownerID: $ref: '#/components/schemas/objectIdString' - description: The _id of the teacher owner of the classroom. description: type: string + code: + type: string + codeCamel: + type: string courses: type: array items: - $ref: '#/components/schemas/Course' + $ref: '#/components/schemas/ClassroomResponseWithCodeCoursesItem' + clanId: + $ref: '#/components/schemas/objectIdString' + ClassroomResponseWithCodeCoursesItem: + type: object + properties: + _id: + $ref: '#/components/schemas/objectIdString' + levels: + type: array + items: + type: object + additionalProperties: {} + enrolled: + type: array + items: + $ref: '#/components/schemas/objectIdString' + instance_id: + $ref: '#/components/schemas/objectIdString' PlaytimeStatsResponse: type: object properties: @@ -1199,23 +1123,75 @@ components: type: number format: double description: Number of active/valid licenses - UserRole: - type: string - enum: - - student - - teacher - description: >- - A `"student"` or `"teacher"`. If unset, a home user will be created, - unable to join classrooms. - HeroConfig: + LevelSessionResponse: type: object properties: - thangType: + state: + $ref: '#/components/schemas/LevelSessionResponseState' + level: + $ref: '#/components/schemas/LevelSessionResponseLevel' + levelID: + type: string + description: Level slug like `wakka-maul` + creator: $ref: '#/components/schemas/objectIdString' + playtime: + type: integer + description: Time played in seconds. + changed: + $ref: '#/components/schemas/datetimeString' + created: + $ref: '#/components/schemas/datetimeString' + dateFirstCompleted: + $ref: '#/components/schemas/datetimeString' + submitted: + type: boolean + description: For arenas. Whether or not the level has been added to the ladder. + published: + type: boolean + description: >- + For shareable projects. Whether or not the project has been shared + with classmates. + LevelSessionResponseState: + type: object + properties: + complete: + type: boolean + LevelSessionResponseLevel: + type: object + properties: + original: + type: string + description: The id for the level. + ClanResponse: + type: object + description: Subset of properties listed here + properties: + _id: + $ref: '#/components/schemas/objectIdString' + name: + type: string + displayName: + type: string + members: + type: array + items: + $ref: '#/components/schemas/objectIdString' + ownerID: + $ref: '#/components/schemas/objectIdString' + description: + type: string + type: + type: string + kind: + type: string + metadata: + type: object + additionalProperties: {} securitySchemes: BasicAuth: type: http scheme: basic servers: - url: https://codecombat.com/api - description: Production + description: default