506 lines
15 KiB
YAML
506 lines
15 KiB
YAML
openapi: 3.0.0
|
|
servers:
|
|
- description: SwaggerHub API Auto Mocking
|
|
url: https://api.skolplattformen.org/
|
|
info:
|
|
version: "1.0.0"
|
|
title: $kolplattformen API
|
|
description: |
|
|
This is a first try to extract a usable API based on the expensive SOA crap that is called Skolplattformen in Stockholm
|
|
|
|
# Introduction
|
|
This API is a wrapper on top of the SOA layer behind **Skolplattformen** which is the mandatory platform for schools in Stockholm Stad.
|
|
|
|
# Get Started
|
|
Generate code examples from the OpenAPI yaml (press Download above) or use this as a start:
|
|
```
|
|
const socialSecurityNumber = '121212121212'
|
|
const baseUrl = 'https://api.skolplattformen.org'
|
|
const token = await fetch(`${baseUrl}/login?socialSecurityNumber=${socialSecurityNumber}`, {method: 'POST'}).then(res => res.json())
|
|
|
|
// Now start BankID and authorize, when you do - your jwt token will be ready
|
|
const jwt = await fetch(`${baseUrl}/login/${token.order}/jwt`).then(res => res.json())
|
|
const headers = {authorization: 'Bearer ' + jwt}
|
|
|
|
// Use the jwt token as bearer token in your requests
|
|
const children = await fetch(`${baseUrl}/children`, {headers}).then(res => res.json())
|
|
|
|
// Get some details
|
|
const childId = children[0].id
|
|
const child = await fetch(`${baseUrl}/children/${childId}`, {headers}).then(res => res.json())
|
|
const news = await fetch(`${baseUrl}/children/${childId}/news`, {headers}).then(res => res.json())
|
|
const calendar = await fetch(`${baseUrl}/children/${childId}/calendar`, {headers}).then(res => res.json())
|
|
|
|
```
|
|
|
|
# Open source
|
|
This project is provided AS IS and is provided free as open source. If you want to participate and add more features to this api. Please find at the repository here:
|
|
[https://github.com/kolplattformen/api](https://github.com/kolplattformen/api)
|
|
|
|
# Privacy considerations
|
|
This API encodes the cookies recieved from the backend servers as JWT tokens and send them encrypted to the client. Neither cookies or tokens are stored on the server.
|
|
|
|
# Disclaimers
|
|
I have no affiliate with the Stockholm Stad organisation or any part of any development team for the city. Therefore things may change and suddenly stop working and I have no way of knowing or even a way of contacting you. My motivation for creating this API is purely for personal reasons. I want to develop apps for my own use and have no interest to go deep in the underlying SDK every day so I'm using this API as a way of creating a little bit of sanity and conform the sometimes swinglish structure into something a little bit more consistant.
|
|
|
|
|
|
contact:
|
|
name: Christian Landgren
|
|
email: christian.landgren@iteam.se
|
|
url: https://github.com/irony
|
|
x-logo:
|
|
url: '/logo.png'
|
|
altText: $kolplattformen
|
|
|
|
|
|
|
|
paths:
|
|
/login:
|
|
post:
|
|
summary: Login
|
|
operationId: login
|
|
description: Get auth cookie for BankID login. This endpoint will initiate a login and require the user to login through BankID. When finished you will recieve a token that can be sent to the status endpoint to recieve a jwt token when authorized through BankID.
|
|
tags:
|
|
- Login
|
|
parameters:
|
|
- name: socialSecurityNumber
|
|
in: query
|
|
description: Swedish social security number connected to BankID
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Auth"
|
|
/login/{order}/jwt:
|
|
get:
|
|
summary: Wait for Jwt token
|
|
operationId: waitForToken
|
|
description: Recieve the status of the order token after the user has approved the authorization request in the BankID app, this endpoint will return a jwt token that can be used for the subsequential requests. This request will wait up until two minutes for a response.
|
|
tags:
|
|
- Login
|
|
parameters:
|
|
- name: order
|
|
in: path
|
|
description: Order token received from the /login endpoint
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AuthToken"
|
|
'408':
|
|
description: Timeout
|
|
/children:
|
|
get:
|
|
operationId: getChildren
|
|
summary: List Children
|
|
security:
|
|
- bearerAuth: []
|
|
description: >-
|
|
Receive a list of children available through the API to the logged in user
|
|
Important to only show children you are eligble to see :)
|
|
tags:
|
|
- Children
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Children"
|
|
'401':
|
|
$ref: '#/components/responses/UnauthorizedError'
|
|
/children/{childId}:
|
|
get:
|
|
operationId: getChildById
|
|
summary: Child
|
|
description: Get all info for this this child
|
|
security:
|
|
- bearerAuth: []
|
|
tags:
|
|
- Children
|
|
parameters:
|
|
- name: childId
|
|
in: path
|
|
description: Child Id (received from /children)
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ChildAll"
|
|
/children/{childId}/news:
|
|
get:
|
|
summary: News
|
|
operationId: getNews
|
|
|
|
description: Get list of news items for this child
|
|
tags:
|
|
- Children
|
|
parameters:
|
|
- name: childId
|
|
in: path
|
|
description: Child Id (received from /children)
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/News"
|
|
|
|
/children/{childId}/calendar:
|
|
get:
|
|
summary: Calendar
|
|
operationId: getCalendar
|
|
|
|
description: Get list of calendar events
|
|
security:
|
|
- bearerAuth: []
|
|
tags:
|
|
- Children
|
|
parameters:
|
|
- name: childId
|
|
in: path
|
|
description: Child Id (received from /children)
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Calendar"
|
|
/children/{childSdsId}/classmates:
|
|
get:
|
|
summary: Classmates
|
|
operationId: getClassmates
|
|
description: Get list of class mates and guardians in this childs class
|
|
security:
|
|
- bearerAuth: []
|
|
tags:
|
|
- Children
|
|
parameters:
|
|
- name: childSdsId
|
|
in: path
|
|
description: Child SdsId (received from /children)
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Classmates"
|
|
/children/{childSdsId}/notifications:
|
|
get:
|
|
summary: Notifications
|
|
operationId: getNotifications
|
|
|
|
description: Get list of notifications for this child
|
|
security:
|
|
- bearerAuth: []
|
|
tags:
|
|
- Children
|
|
parameters:
|
|
- name: childSdsId
|
|
in: path
|
|
description: Child sdsId (received from /children) (this is a separate id than childId for some reason, probably a subsystem)
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Notifications"
|
|
/children/{childId}/menu:
|
|
get:
|
|
summary: Lunch Menu
|
|
operationId: getMenu
|
|
|
|
description: Get food menu for the week for this child
|
|
security:
|
|
- bearerAuth: []
|
|
tags:
|
|
- Children
|
|
parameters:
|
|
- name: childId
|
|
in: path
|
|
description: Child Id (received from /children)
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
/children/{childSdsId}/schedule:
|
|
get:
|
|
summary: Schedule
|
|
operationId: getSchedule
|
|
|
|
description: Get list of news items for this child
|
|
security:
|
|
- bearerAuth: []
|
|
tags:
|
|
- Children
|
|
parameters:
|
|
- name: childSdsId
|
|
in: path
|
|
description: Child SdsId (received from /children) (this is a separate id than childId for some reason, probably a subsystem)
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
/download/:
|
|
get:
|
|
summary: Download
|
|
operationId: download
|
|
|
|
description: Download content from an url using the jwt token
|
|
security:
|
|
- bearerAuth: []
|
|
tags:
|
|
- Utility
|
|
parameters:
|
|
- name: url
|
|
in: query
|
|
description: URL to download
|
|
example: /vardnadshavare/content/img.jpg
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
'404':
|
|
description: Not Found
|
|
components:
|
|
schemas:
|
|
|
|
Auth:
|
|
type: object
|
|
properties:
|
|
token:
|
|
type: string
|
|
format: uuid
|
|
order:
|
|
type: string
|
|
format: uuid
|
|
|
|
AuthToken:
|
|
type: object
|
|
description: "A JWT token that should be used for authorizing requests"
|
|
properties:
|
|
jwt:
|
|
type: string
|
|
|
|
News:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/NewsItem"
|
|
|
|
NewsItem:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
header:
|
|
type: string
|
|
example: "Nya direktiv från folkhälsomyndigheten"
|
|
intro:
|
|
type: string
|
|
example: "Nedan följer viktig information till dig som förälder med barn"
|
|
body:
|
|
type: string
|
|
example: "Hej\n\nNedan följer viktig information t..."
|
|
published:
|
|
type: string
|
|
example: "2020-12-24T14:00:00.966Z"
|
|
modified:
|
|
type: string
|
|
example: "2020-12-24T14:00:00.966Z"
|
|
imageUrl:
|
|
type: string
|
|
description: "A news item from the school, for example a weekly news letter"
|
|
|
|
Calendar:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/CalendarItem"
|
|
|
|
CalendarItem:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
title:
|
|
type: string
|
|
example: "Tidig stängning"
|
|
description:
|
|
type: string
|
|
example: "På torsdag stänger vi 15:45 på grund av Lucia"
|
|
location:
|
|
type: string
|
|
example: ""
|
|
startDate:
|
|
type: string
|
|
format: date
|
|
example: "2020-12-13"
|
|
endDate:
|
|
type: string
|
|
format: date
|
|
example: "2020-12-13"
|
|
allDay:
|
|
type: boolean
|
|
example: true
|
|
ChildAll:
|
|
type: object
|
|
properties:
|
|
child:
|
|
$ref: "#/components/schemas/Child"
|
|
news:
|
|
$ref: "#/components/schemas/News"
|
|
calendar:
|
|
$ref: "#/components/schemas/Calendar"
|
|
notifications:
|
|
$ref: "#/components/schemas/Notifications"
|
|
|
|
Classmates:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Classmate"
|
|
Classmate:
|
|
type: object
|
|
properties:
|
|
sisId:
|
|
type: string
|
|
format: uuid
|
|
className:
|
|
type: string
|
|
description: The name of the class of this classmate
|
|
example: "8C"
|
|
firstname:
|
|
type: string
|
|
example: "Max"
|
|
lastname:
|
|
type: string
|
|
example: "Svensson"
|
|
guardians:
|
|
type: object
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
example: allan@svensson.se
|
|
firstname:
|
|
type: string
|
|
example: Allan
|
|
lastname:
|
|
type: string
|
|
example: Svensson
|
|
mobile:
|
|
type: string
|
|
example: 070-13372121
|
|
address:
|
|
type: string
|
|
example: Vallebyvägen 13b, lgh 223A
|
|
|
|
Notifications:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Notification"
|
|
Notification:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
example: "133869-e254-487a-ac4a-2ab6e5dabeec"
|
|
sender.name:
|
|
type: string
|
|
example: "Elevdokumentation"
|
|
dateCreated:
|
|
type: string
|
|
format: date-time
|
|
example: "2020-12-10T14:31:29.966Z"
|
|
message:
|
|
type: string
|
|
example: "Nu kan du ta del av ditt barns dokumentation av utvecklingssamtal"
|
|
url:
|
|
type: string
|
|
example: "https://elevdokumentation.stockholm.se/mvvm/loa3/conference/guardian/student/802003_sthlm/documents/38383838-1111-4f3a-b022-94d24ed72b31"
|
|
description: "URL with the actual message as a webpage. Needs separate login. TODO: Investigate how to solve this somehow"
|
|
category:
|
|
type: string
|
|
example: "Lärlogg"
|
|
messageType:
|
|
type: string
|
|
example: "avisering"
|
|
|
|
Children:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Child"
|
|
Child:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
sdsId:
|
|
type: string
|
|
format: uuid
|
|
description: Special ID used to access certain subsystems
|
|
name:
|
|
type: string
|
|
example: "Kalle Svensson (elev)"
|
|
status:
|
|
type: string
|
|
description: F - förskola, GR - grundskola?
|
|
example: "F;GR"
|
|
schoolId:
|
|
type: string
|
|
format: uuid
|
|
example: "133372F4-AF59-613D-1636-543EC3652111"
|
|
responses:
|
|
UnauthorizedError:
|
|
description: Access token is missing or invalid
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: |
|
|
This API uses JWT tokens to authorize requests. To recieve a JWT token you have to
|
|
1. Initiate a login session through the [/login](/login) endpoint. This will trigger a BankID login.
|
|
2. After this you can query the /login/{order}/jwt endpoint which will return a JWT token when the user has finished authorizing the request in their BankID app.
|
|
|
|
The token contains a session cookie which will expire. If you receive an error message when using the expired token, please repeat the process.
|