mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2025-08-03 18:29:14 +02:00
feat:#36 added new event grpc message
This commit is contained in:
@@ -131,25 +131,37 @@ func findEventByDayWeekStartEndNameCourse(event model.Event, course string, dao
|
||||
}
|
||||
}
|
||||
|
||||
func buildIcalQueryForModules(modules []model.FeedCollection) dbx.Expression {
|
||||
func buildIcalQueryForModules(modulesUuid []string) dbx.Expression {
|
||||
|
||||
// check uuids against sql injection
|
||||
// uuids are generated by the system and are not user input
|
||||
// following the pattern of only containing alphanumeric characters and dashes
|
||||
|
||||
for _, moduleUuid := range modulesUuid {
|
||||
if !IsSafeIdentifier(moduleUuid) {
|
||||
slog.Warn("Module UUID is not safe: ", "moduleUuid", moduleUuid)
|
||||
return dbx.HashExp{}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build where conditions for each module
|
||||
|
||||
//first check if modules is empty
|
||||
if len(modules) == 0 {
|
||||
if len(modulesUuid) == 0 {
|
||||
return dbx.HashExp{}
|
||||
}
|
||||
|
||||
//second check if modules has only one element
|
||||
if len(modules) == 1 {
|
||||
return dbx.HashExp{"uuid": modules[0].UUID}
|
||||
if len(modulesUuid) == 1 {
|
||||
return dbx.HashExp{"uuid": modulesUuid[0]}
|
||||
}
|
||||
|
||||
//third check if modules has more than one element
|
||||
var wheres []dbx.Expression
|
||||
|
||||
for _, module := range modules {
|
||||
where := dbx.HashExp{"uuid": module.UUID}
|
||||
for _, moduleUuid := range modulesUuid {
|
||||
where := dbx.HashExp{"uuid": moduleUuid}
|
||||
wheres = append(wheres, where)
|
||||
}
|
||||
|
||||
@@ -162,18 +174,18 @@ func buildIcalQueryForModules(modules []model.FeedCollection) dbx.Expression {
|
||||
|
||||
// GetPlanForModules returns all events for the given modules with the given course
|
||||
// used for the ical feed
|
||||
func GetPlanForModules(app *pocketbase.PocketBase, modules map[string]model.FeedCollection) (model.Events, error) {
|
||||
func GetPlanForModules(app *pocketbase.PocketBase, modules []string) (model.Events, error) {
|
||||
|
||||
var events model.Events
|
||||
|
||||
modulesArray := make([]model.FeedCollection, 0, len(modules))
|
||||
modulesArray := make([]string, 0, len(modules))
|
||||
for _, value := range modules {
|
||||
modulesArray = append(modulesArray, value)
|
||||
}
|
||||
|
||||
// iterate over modules in 100 batch sizes
|
||||
for i := 0; i < len(modules); i += 100 {
|
||||
var moduleBatch []model.FeedCollection
|
||||
var moduleBatch []string
|
||||
|
||||
if i+100 > len(modules) {
|
||||
moduleBatch = modulesArray[i:]
|
||||
|
@@ -18,14 +18,13 @@ package db
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/dbx"
|
||||
"htwkalender/data-manager/model"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_buildIcalQueryForModules(t *testing.T) {
|
||||
type args struct {
|
||||
modules []model.FeedCollection
|
||||
modules []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -34,17 +33,17 @@ func Test_buildIcalQueryForModules(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "empty modules",
|
||||
args: args{modules: []model.FeedCollection{}},
|
||||
args: args{modules: []string{}},
|
||||
want: dbx.HashExp{},
|
||||
},
|
||||
{
|
||||
name: "one module",
|
||||
args: args{modules: []model.FeedCollection{{Name: "test", Course: "test", UUID: "test"}}},
|
||||
args: args{modules: []string{"test"}},
|
||||
want: dbx.HashExp{"uuid": "test"},
|
||||
},
|
||||
{
|
||||
name: "two modules",
|
||||
args: args{modules: []model.FeedCollection{{Name: "test", Course: "test", UUID: "test"}, {Name: "test2", Course: "test2", UUID: "test2"}}},
|
||||
args: args{modules: []string{"test", "test2"}},
|
||||
want: dbx.Or(dbx.HashExp{"uuid": "test"}, dbx.HashExp{"uuid": "test2"}),
|
||||
},
|
||||
}
|
||||
|
@@ -19,9 +19,26 @@ package db
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase"
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"log/slog"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func FindCollection(app *pocketbase.PocketBase, collectionName string) (*models.Collection, error) {
|
||||
collection, dbError := app.Dao().FindCollectionByNameOrId(collectionName)
|
||||
return collection, dbError
|
||||
}
|
||||
|
||||
// IsSafeIdentifier check uuids against sql injection
|
||||
// uuids are generated by the system and are not user input
|
||||
// following the pattern of only containing alphanumeric characters and dashes
|
||||
func IsSafeIdentifier(uuid string) bool {
|
||||
// Define a regular expression that matches only valid UUID characters (alphanumeric and dashes)
|
||||
validUUIDPattern := `^[a-zA-Z0-9-]+$`
|
||||
match, err := regexp.MatchString(validUUIDPattern, uuid)
|
||||
if err != nil {
|
||||
// Handle the error according to your application's needs
|
||||
slog.Warn("Invalid UUID pattern", "uuid", uuid)
|
||||
return false
|
||||
}
|
||||
return match
|
||||
}
|
||||
|
50
services/data-manager/service/db/dbFunctions_test.go
Normal file
50
services/data-manager/service/db/dbFunctions_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package db
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestIsSafeIdentifier(t *testing.T) {
|
||||
type args struct {
|
||||
uuid string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "Test safe identifier",
|
||||
args: args{
|
||||
uuid: "1234567890-1234567890-1234567890-1234567890",
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Test safe identifier",
|
||||
args: args{
|
||||
uuid: "1234567890-1234567890-1234567890-1234567890",
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Test safe identifier",
|
||||
args: args{
|
||||
uuid: "77eddc32-c49d-5d0a-8c36-17b266396641",
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Test unsafe identifier",
|
||||
args: args{
|
||||
uuid: "77eddc32-c49d-5d0a-8c36-17/1!!b266396641-",
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := IsSafeIdentifier(tt.args.uuid); got != tt.want {
|
||||
t.Errorf("IsSafeIdentifier() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@@ -23,3 +23,11 @@ func eventToProto(event *model.Event) *pb.Event {
|
||||
Semester: event.Semester,
|
||||
}
|
||||
}
|
||||
|
||||
func eventsToProto(events model.Events) []*pb.Event {
|
||||
protoEvents := make([]*pb.Event, 0)
|
||||
for _, event := range events {
|
||||
protoEvents = append(protoEvents, eventToProto(&event))
|
||||
}
|
||||
return protoEvents
|
||||
}
|
||||
|
@@ -67,3 +67,15 @@ func StartGRPCServer(app *pocketbase.PocketBase) {
|
||||
log.Fatalf("failed to serve: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ModulesGrpcHandler) GetEventsForModules(ctx context.Context, in *pb.GetModulesRequest) (*pb.GetEventsResponse, error) {
|
||||
|
||||
events, err := db.GetPlanForModules(s.app, in.Uuids)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.GetEventsResponse{
|
||||
Events: eventsToProto(events),
|
||||
}, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user