Merge pull request #77 from HTWK-Leipzig/74-security-for-endpoints

74 security for endpoints
This commit is contained in:
masterElmar
2023-11-20 17:40:58 +01:00
committed by GitHub
7 changed files with 206 additions and 31 deletions

View File

@@ -35,6 +35,14 @@ htwkalender-demo
Execute the following api calls to fetch data manually from HTWK and store it in the database:
Both api calls need a token to be executed.
You can get a token by logging in to the admin ui and copy the token from the local storage.
Add this attribute to the request header of the api call:
```
Authorization : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDE3MDA3ODQsImlkIjoicnA0Ym54YXNyczM5emR4IiwidHlwZSI6ImFkbWluIn0.j7Bt3-uaZ8CoNt8D9Oxjk7ZwvHDGZJy1xe3aq4BID3w
```
The first command will fetch all groups and store them in the database.
This should be done quick in a few seconds (0-5s).
When you execute the command again, it will update the groups in the

View File

@@ -1,10 +1,10 @@
package model
type Module struct {
UUID string `json:"uuid"`
Name string `json:"name"`
Prof string `json:"prof"`
Course string `json:"course"`
Semester string `json:"semester"`
UUID string `json:"uuid" db:"uuid"`
Name string `json:"name" db:"Name"`
Prof string `json:"prof" db:"Prof"`
Course string `json:"course" db:"course"`
Semester string `json:"semester" db:"semester"`
Events Events `json:"events"`
}

View File

@@ -11,12 +11,24 @@ paths:
/api/fetchPlans:
get:
summary: Fetch Seminar Plans
security:
- ApiKeyAuth: []
responses:
'200':
description: Successful response
/api/fetchGroups:
get:
summary: Fetch Seminar Groups
security:
- ApiKeyAuth: []
responses:
'200':
description: Successful response
/api/modules:
delete:
summary: Delete Module
security:
- ApiKeyAuth: []
responses:
'200':
description: Successful response
@@ -26,15 +38,123 @@ paths:
responses:
'200':
description: Successful response
/api/feedURL:
/api/schedule/day:
get:
summary: Get iCal Feed URL
summary: Get Day Schedule
parameters:
- name: room
in: query
description: room
example: "LN006-H"
required: true
schema:
type: string
- name: date
in: query
description: date
example: "2023-11-26"
required: true
schema:
type: string
responses:
'200':
description: Successful response
/api/schedule:
get:
summary: Get Schedule
parameters:
- name: room
in: query
description: room
example: "LN006-H"
required: true
schema:
type: string
- name: from
in: query
description: date
example: "2023-11-26"
required: true
schema:
type: string
- name: to
in: query
description: date
example: "2023-11-30"
required: true
schema:
type: string
responses:
'200':
description: Successful response
/api/createFeed:
post:
summary: Create iCal Feed
requestBody:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Module'
required:
- name
- modules
responses:
'200':
description: Successful response
/api/feed:
get:
summary: Get iCal Feed for calendar
parameters:
- name: token
in: query
description: calendar token
required: true
example: "ldluwzg3e73ffxq"
schema:
type: string
responses:
'200':
description: Successful response
/api/course/modules:
get:
summary: Get Modules for Course
parameters:
- name: course
in: query
description: course
required: true
example: "Software Engineering"
schema:
type: string
- name: semester
in: query
description: semester
required: true
example: "ws"
schema:
type: string
responses:
'200':
description: Successful response
/api/module:
get:
summary: Get Module
parameters:
- name: uuid
in: query
description: uuid
required: true
example: "d0b3a0e0-2f1a-4e1a-8b0a-0b9e1a0b9e1a"
schema:
type: string
responses:
'200':
description: Successful response
/api/courses:
get:
summary: Get Courses
responses:
'200':
description: Successful response
@@ -51,3 +171,52 @@ paths:
responses:
'200':
description: Successful response
/api/events:
delete:
summary: Delete Event
security:
- ApiKeyAuth: []
responses:
'200':
description: Successful response
/api/feeds/migrate:
get:
summary: Migrates all iCal Feeds in the database to the new format
security:
- ApiKeyAuth: []
responses:
'200':
description: Successful response
security:
- ApiKeyAuth: []
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: Authorization
schemas:
Module:
type: object
properties:
name:
type: string
description: name
example: "Software Engineering"
uuid:
type: string
format: uuid
course:
type: string
userDefinedName:
type: string
prof:
type: string
semester:
type: string
reminder:
type: boolean
events:
type: array
items:
type: string

View File

@@ -1,7 +1,6 @@
package service
import (
"htwkalender/model"
"htwkalender/service/events"
"htwkalender/service/fetch"
"htwkalender/service/ical"
@@ -26,6 +25,7 @@ func AddRoutes(app *pocketbase.PocketBase) {
},
Middlewares: []echo.MiddlewareFunc{
apis.ActivityLogger(app),
apis.RequireAdminAuth(),
},
})
if err != nil {
@@ -61,6 +61,7 @@ func AddRoutes(app *pocketbase.PocketBase) {
},
Middlewares: []echo.MiddlewareFunc{
apis.ActivityLogger(app),
apis.RequireAdminAuth(),
},
})
if err != nil {
@@ -212,18 +213,11 @@ func AddRoutes(app *pocketbase.PocketBase) {
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
_, err := e.Router.AddRoute(echo.Route{
Method: http.MethodPost,
Method: http.MethodGet,
Path: "/api/module",
Handler: func(c echo.Context) error {
var requestModule model.Module
if err := c.Bind(&requestModule); err != nil {
return apis.NewBadRequestError("Failed to read request body", err)
}
module, err := events.GetModuleByName(app, requestModule)
requestModule := c.QueryParam("uuid")
module, err := events.GetModuleByUUID(app, requestModule)
if err != nil {
return c.JSON(400, err)
} else {
@@ -286,7 +280,7 @@ func AddRoutes(app *pocketbase.PocketBase) {
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
_, err := e.Router.AddRoute(echo.Route{
Method: http.MethodGet,
Path: "/api/feed/migrate",
Path: "/api/feeds/migrate",
Handler: func(c echo.Context) error {
err := ical.MigrateFeedJson(app)

View File

@@ -196,6 +196,18 @@ func DeleteAllEvents(app *pocketbase.PocketBase) error {
return nil
}
func FindModuleByUUID(app *pocketbase.PocketBase, uuid string) (model.Module, error) {
var module model.Module
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("uuid = {:uuid}", dbx.Params{"uuid": uuid})).One(&module)
if err != nil {
print("Error while getting events from database: ", err)
return model.Module{}, err
}
return module, nil
}
func FindAllEventsByModule(app *pocketbase.PocketBase, module model.Module) (model.Events, error) {
var events model.Events

View File

@@ -42,11 +42,8 @@ func GetAllModulesDistinct(app *pocketbase.PocketBase, c echo.Context) error {
}
}
// GetModuleByName returns a module by its name
// If the module does not exist, an error is returned
// If the module exists, the module is returned
// Module is a struct that exists in database as events
func GetModuleByName(app *pocketbase.PocketBase, module model.Module) (model.Module, error) {
func GetModuleByUUID(app *pocketbase.PocketBase, uuid string) (model.Module, error) {
module, err := db.FindModuleByUUID(app, uuid)
events, err := db.FindAllEventsByModule(app, module)
if err != nil || len(events) == 0 {

View File

@@ -1,13 +1,8 @@
import { Module } from "../model/module";
export async function fetchModule(module: Module): Promise<Module> {
const request = new Request("/api/module", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(module),
});
// request to the backend on /api/module with query parameters name as the module name
const request = new Request("/api/module?uuid=" + module.uuid);
return await fetch(request)
.then((response) => {