feat:#36 added new event grpc message

This commit is contained in:
Elmar Kresse
2024-06-18 12:50:21 +02:00
parent 56e77630b5
commit 08140b5802
14 changed files with 510 additions and 50 deletions

View File

@@ -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:]

View File

@@ -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"}),
},
}

View File

@@ -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
}

View 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)
}
})
}
}

View File

@@ -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
}

View File

@@ -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
}