From c817bfc8c8b5e4692eb2d41737c969331da2b1c7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sun, 13 Apr 2025 13:46:09 -0700 Subject: [PATCH 1/4] validator: flatten check matches --- validation/src/check_mapfix.rs | 53 +++++++++++++---------------- validation/src/check_submission.rs | 54 +++++++++++++----------------- 2 files changed, 47 insertions(+), 60 deletions(-) diff --git a/validation/src/check_mapfix.rs b/validation/src/check_mapfix.rs index f5aec5b..de95811 100644 --- a/validation/src/check_mapfix.rs +++ b/validation/src/check_mapfix.rs @@ -21,37 +21,30 @@ impl crate::message_handler::MessageHandler{ // update the mapfix depending on the result match check_result{ - Ok(CheckReportAndVersion{status,version})=>{ - match status{ - // update the mapfix model status to submitted - Ok(map_info)=>self.api.action_mapfix_submitted( - submissions_api::types::ActionMapfixSubmittedRequest{ - MapfixID:mapfix_id, - ModelVersion:version, - DisplayName:map_info.display_name, - Creator:map_info.creator, - GameID:map_info.game_id as u32, - } - ).await.map_err(Error::ApiActionMapfixCheck)?, - // update the mapfix model status to request changes - Err(report)=>self.api.action_mapfix_request_changes( - submissions_api::types::ActionMapfixRequestChangesRequest{ - MapfixID:mapfix_id, - ErrorMessage:report, - } - ).await.map_err(Error::ApiActionMapfixCheck)?, + Ok(CheckReportAndVersion{status:Ok(map_info),version})=>self.api.action_mapfix_submitted( + submissions_api::types::ActionMapfixSubmittedRequest{ + MapfixID:mapfix_id, + ModelVersion:version, + DisplayName:map_info.display_name, + Creator:map_info.creator, + GameID:map_info.game_id as u32, } - }, - Err(e)=>{ - // TODO: report the error - // update the mapfix model status to request changes - self.api.action_mapfix_request_changes( - submissions_api::types::ActionMapfixRequestChangesRequest{ - MapfixID:mapfix_id, - ErrorMessage:e.to_string(), - } - ).await.map_err(Error::ApiActionMapfixCheck)?; - }, + ).await.map_err(Error::ApiActionMapfixCheck)?, + // update the mapfix model status to request changes + Ok(CheckReportAndVersion{status:Err(report),..})=>self.api.action_mapfix_request_changes( + submissions_api::types::ActionMapfixRequestChangesRequest{ + MapfixID:mapfix_id, + ErrorMessage:report, + } + ).await.map_err(Error::ApiActionMapfixCheck)?, + // TODO: report the error + // update the mapfix model status to request changes + Err(e)=>self.api.action_mapfix_request_changes( + submissions_api::types::ActionMapfixRequestChangesRequest{ + MapfixID:mapfix_id, + ErrorMessage:e.to_string(), + } + ).await.map_err(Error::ApiActionMapfixCheck)?, } Ok(()) diff --git a/validation/src/check_submission.rs b/validation/src/check_submission.rs index 1440a10..4140539 100644 --- a/validation/src/check_submission.rs +++ b/validation/src/check_submission.rs @@ -21,37 +21,31 @@ impl crate::message_handler::MessageHandler{ // update the submission depending on the result match check_result{ - Ok(CheckReportAndVersion{status,version})=>{ - match status{ - // update the submission model status to submitted - Ok(map_info)=>self.api.action_submission_submitted( - submissions_api::types::ActionSubmissionSubmittedRequest{ - SubmissionID:submission_id, - ModelVersion:version, - DisplayName:map_info.display_name, - Creator:map_info.creator, - GameID:map_info.game_id as u32, - } - ).await.map_err(Error::ApiActionSubmissionCheck)?, - // update the submission model status to request changes - Err(report)=>self.api.action_submission_request_changes( - submissions_api::types::ActionSubmissionRequestChangesRequest{ - SubmissionID:submission_id, - ErrorMessage:report, - } - ).await.map_err(Error::ApiActionSubmissionCheck)?, + // update the submission model status to submitted + Ok(CheckReportAndVersion{status:Ok(map_info),version})=>self.api.action_submission_submitted( + submissions_api::types::ActionSubmissionSubmittedRequest{ + SubmissionID:submission_id, + ModelVersion:version, + DisplayName:map_info.display_name, + Creator:map_info.creator, + GameID:map_info.game_id as u32, } - }, - Err(e)=>{ - // TODO: report the error - // update the submission model status to request changes - self.api.action_submission_request_changes( - submissions_api::types::ActionSubmissionRequestChangesRequest{ - SubmissionID:submission_id, - ErrorMessage:e.to_string(), - } - ).await.map_err(Error::ApiActionSubmissionCheck)?; - }, + ).await.map_err(Error::ApiActionSubmissionCheck)?, + // update the submission model status to request changes + Ok(CheckReportAndVersion{status:Err(report),..})=>self.api.action_submission_request_changes( + submissions_api::types::ActionSubmissionRequestChangesRequest{ + SubmissionID:submission_id, + ErrorMessage:report, + } + ).await.map_err(Error::ApiActionSubmissionCheck)?, + // TODO: report the error + // update the submission model status to request changes + Err(e)=>self.api.action_submission_request_changes( + submissions_api::types::ActionSubmissionRequestChangesRequest{ + SubmissionID:submission_id, + ErrorMessage:e.to_string(), + } + ).await.map_err(Error::ApiActionSubmissionCheck)?, } Ok(()) -- 2.49.1 From 9e42050a6508b881f8990691628f9339cc1efef4 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sun, 13 Apr 2025 16:31:37 -0700 Subject: [PATCH 2/4] openapi: include usernames in AuditEvent --- openapi.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openapi.yaml b/openapi.yaml index 69ea9bb..2e94f30 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1318,6 +1318,7 @@ components: - ID - Date - User + - Username - ResourceType - ResourceID - EventType @@ -1332,6 +1333,9 @@ components: User: type: integer format: int64 + Username: + type: string + maxLength: 64 ResourceType: type: integer format: int32 -- 2.49.1 From 5ba52ecb577d5ab4cba15afce9203d90de481fe7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sun, 13 Apr 2025 16:31:42 -0700 Subject: [PATCH 3/4] openapi: generate --- pkg/api/oas_json_gen.go | 37 ++++++++++++++++++++-------- pkg/api/oas_response_decoders_gen.go | 34 +++++++++++++++++++++++++ pkg/api/oas_schemas_gen.go | 17 ++++++++++--- pkg/api/oas_validators_gen.go | 31 +++++++++++++++++++++++ 4 files changed, 106 insertions(+), 13 deletions(-) diff --git a/pkg/api/oas_json_gen.go b/pkg/api/oas_json_gen.go index 5f84a66..c90351c 100644 --- a/pkg/api/oas_json_gen.go +++ b/pkg/api/oas_json_gen.go @@ -34,6 +34,10 @@ func (s *AuditEvent) encodeFields(e *jx.Encoder) { e.FieldStart("User") e.Int64(s.User) } + { + e.FieldStart("Username") + e.Str(s.Username) + } { e.FieldStart("ResourceType") e.Int32(s.ResourceType) @@ -52,14 +56,15 @@ func (s *AuditEvent) encodeFields(e *jx.Encoder) { } } -var jsonFieldsNameOfAuditEvent = [7]string{ +var jsonFieldsNameOfAuditEvent = [8]string{ 0: "ID", 1: "Date", 2: "User", - 3: "ResourceType", - 4: "ResourceID", - 5: "EventType", - 6: "EventData", + 3: "Username", + 4: "ResourceType", + 5: "ResourceID", + 6: "EventType", + 7: "EventData", } // Decode decodes AuditEvent from json. @@ -107,8 +112,20 @@ func (s *AuditEvent) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"User\"") } - case "ResourceType": + case "Username": requiredBitSet[0] |= 1 << 3 + if err := func() error { + v, err := d.Str() + s.Username = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Username\"") + } + case "ResourceType": + requiredBitSet[0] |= 1 << 4 if err := func() error { v, err := d.Int32() s.ResourceType = int32(v) @@ -120,7 +137,7 @@ func (s *AuditEvent) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"ResourceType\"") } case "ResourceID": - requiredBitSet[0] |= 1 << 4 + requiredBitSet[0] |= 1 << 5 if err := func() error { v, err := d.Int64() s.ResourceID = int64(v) @@ -132,7 +149,7 @@ func (s *AuditEvent) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"ResourceID\"") } case "EventType": - requiredBitSet[0] |= 1 << 5 + requiredBitSet[0] |= 1 << 6 if err := func() error { v, err := d.Int32() s.EventType = int32(v) @@ -144,7 +161,7 @@ func (s *AuditEvent) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"EventType\"") } case "EventData": - requiredBitSet[0] |= 1 << 6 + requiredBitSet[0] |= 1 << 7 if err := func() error { if err := s.EventData.Decode(d); err != nil { return err @@ -163,7 +180,7 @@ func (s *AuditEvent) Decode(d *jx.Decoder) error { // Validate required fields. var failures []validate.FieldError for i, mask := range [1]uint8{ - 0b01111111, + 0b11111111, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. diff --git a/pkg/api/oas_response_decoders_gen.go b/pkg/api/oas_response_decoders_gen.go index e6336d5..d92f378 100644 --- a/pkg/api/oas_response_decoders_gen.go +++ b/pkg/api/oas_response_decoders_gen.go @@ -2511,6 +2511,23 @@ func decodeListMapfixAuditEventsResponse(resp *http.Response) (res []AuditEvent, if response == nil { return errors.New("nil is invalid value") } + var failures []validate.FieldError + for i, elem := range response { + if err := func() error { + if err := elem.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: fmt.Sprintf("[%d]", i), + Error: err, + }) + } + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } return nil }(); err != nil { return res, errors.Wrap(err, "validate") @@ -3099,6 +3116,23 @@ func decodeListSubmissionAuditEventsResponse(resp *http.Response) (res []AuditEv if response == nil { return errors.New("nil is invalid value") } + var failures []validate.FieldError + for i, elem := range response { + if err := func() error { + if err := elem.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: fmt.Sprintf("[%d]", i), + Error: err, + }) + } + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } return nil }(); err != nil { return res, errors.Wrap(err, "validate") diff --git a/pkg/api/oas_schemas_gen.go b/pkg/api/oas_schemas_gen.go index 31dc5ea..c55d7b4 100644 --- a/pkg/api/oas_schemas_gen.go +++ b/pkg/api/oas_schemas_gen.go @@ -76,9 +76,10 @@ type ActionSubmissionValidatedNoContent struct{} // Ref: #/components/schemas/AuditEvent type AuditEvent struct { - ID int64 `json:"ID"` - Date int64 `json:"Date"` - User int64 `json:"User"` + ID int64 `json:"ID"` + Date int64 `json:"Date"` + User int64 `json:"User"` + Username string `json:"Username"` // Is this a submission or is it a mapfix. ResourceType int32 `json:"ResourceType"` ResourceID int64 `json:"ResourceID"` @@ -102,6 +103,11 @@ func (s *AuditEvent) GetUser() int64 { return s.User } +// GetUsername returns the value of Username. +func (s *AuditEvent) GetUsername() string { + return s.Username +} + // GetResourceType returns the value of ResourceType. func (s *AuditEvent) GetResourceType() int32 { return s.ResourceType @@ -137,6 +143,11 @@ func (s *AuditEvent) SetUser(val int64) { s.User = val } +// SetUsername sets the value of Username. +func (s *AuditEvent) SetUsername(val string) { + s.Username = val +} + // SetResourceType sets the value of ResourceType. func (s *AuditEvent) SetResourceType(val int32) { s.ResourceType = val diff --git a/pkg/api/oas_validators_gen.go b/pkg/api/oas_validators_gen.go index 4f60361..b636337 100644 --- a/pkg/api/oas_validators_gen.go +++ b/pkg/api/oas_validators_gen.go @@ -10,6 +10,37 @@ import ( "github.com/ogen-go/ogen/validate" ) +func (s *AuditEvent) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if err := (validate.String{ + MinLength: 0, + MinLengthSet: false, + MaxLength: 64, + MaxLengthSet: true, + Email: false, + Hostname: false, + Regex: nil, + }).Validate(string(s.Username)); err != nil { + return errors.Wrap(err, "string") + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "Username", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + func (s *Error) Validate() error { if s == nil { return validate.ErrNilPointer -- 2.49.1 From 6a8da7ed8a2caa3202ced54d68ae673b79df70cd Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sun, 13 Apr 2025 16:30:45 -0700 Subject: [PATCH 4/4] submissions: fetch usernames from data service --- pkg/cmds/serve.go | 4 +++- pkg/service/audit_events.go | 27 +++++++++++++++++++++++++++ pkg/service/mapfixes.go | 2 +- pkg/service/maps.go | 4 ++-- pkg/service/service.go | 4 +++- pkg/service/submissions.go | 2 +- 6 files changed, 37 insertions(+), 6 deletions(-) diff --git a/pkg/cmds/serve.go b/pkg/cmds/serve.go index ccab4cd..0309c9e 100644 --- a/pkg/cmds/serve.go +++ b/pkg/cmds/serve.go @@ -6,6 +6,7 @@ import ( "git.itzana.me/strafesnet/go-grpc/auth" "git.itzana.me/strafesnet/go-grpc/maps" + "git.itzana.me/strafesnet/go-grpc/users" "git.itzana.me/strafesnet/maps-service/pkg/api" "git.itzana.me/strafesnet/maps-service/pkg/datastore/gormstore" internal "git.itzana.me/strafesnet/maps-service/pkg/internal" @@ -125,7 +126,8 @@ func serve(ctx *cli.Context) error { svc := &service.Service{ DB: db, Nats: js, - Client: maps.NewMapsServiceClient(conn), + Maps: maps.NewMapsServiceClient(conn), + Users: users.NewUsersServiceClient(conn), } conn, err = grpc.Dial(ctx.String("auth-rpc-host"), grpc.WithTransportCredentials(insecure.NewCredentials())) diff --git a/pkg/service/audit_events.go b/pkg/service/audit_events.go index 61dd65a..01417ca 100644 --- a/pkg/service/audit_events.go +++ b/pkg/service/audit_events.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" + "git.itzana.me/strafesnet/go-grpc/users" "git.itzana.me/strafesnet/maps-service/pkg/api" "git.itzana.me/strafesnet/maps-service/pkg/datastore" "git.itzana.me/strafesnet/maps-service/pkg/model" @@ -83,6 +84,27 @@ func (svc *Service) ListMapfixAuditEvents(ctx context.Context, params api.ListMa return nil, err } + idMap := make(map[int64]bool) + for _, item := range items { + idMap[int64(item.User)] = true + } + + var idList users.IdList + idList.ID = make([]int64,len(idMap)) + for userId := range idMap { + idList.ID = append(idList.ID, userId) + } + + userList, err := svc.Users.GetList(ctx, &idList) + if err != nil { + return nil, err + } + + userMap := make(map[int64]*users.UserResponse) + for _,user := range userList.Users { + userMap[user.ID] = user + } + var resp []api.AuditEvent for _, item := range items { EventData := api.AuditEventEventData{} @@ -90,10 +112,15 @@ func (svc *Service) ListMapfixAuditEvents(ctx context.Context, params api.ListMa if err != nil { return nil, err } + username := "" + if userMap[int64(item.User)] != nil { + username = userMap[int64(item.User)].Username + } resp = append(resp, api.AuditEvent{ ID: item.ID, Date: item.CreatedAt.Unix(), User: int64(item.User), + Username: username, ResourceType: int32(item.ResourceType), ResourceID: item.ResourceID, EventType: int32(item.EventType), diff --git a/pkg/service/mapfixes.go b/pkg/service/mapfixes.go index 8c42171..1712afd 100644 --- a/pkg/service/mapfixes.go +++ b/pkg/service/mapfixes.go @@ -78,7 +78,7 @@ func (svc *Service) CreateMapfix(ctx context.Context, request *api.MapfixTrigger // Check if TargetAssetID actually exists { - _, err := svc.Client.Get(ctx, &maps.IdMessage{ + _, err := svc.Maps.Get(ctx, &maps.IdMessage{ ID: request.TargetAssetID, }) if err != nil { diff --git a/pkg/service/maps.go b/pkg/service/maps.go index f789da6..aa7b52f 100644 --- a/pkg/service/maps.go +++ b/pkg/service/maps.go @@ -25,7 +25,7 @@ func (svc *Service) ListMaps(ctx context.Context, params api.ListMapsParams) ([] filter.GameID = ¶ms.GameID.Value } - mapList, err := svc.Client.List(ctx, &maps.ListRequest{ + mapList, err := svc.Maps.List(ctx, &maps.ListRequest{ Filter: &filter, Page: &maps.Pagination{ Size: params.Limit, @@ -56,7 +56,7 @@ func (svc *Service) ListMaps(ctx context.Context, params api.ListMapsParams) ([] // // GET /maps/{MapID} func (svc *Service) GetMap(ctx context.Context, params api.GetMapParams) (*api.Map, error) { - mapResponse, err := svc.Client.Get(ctx, &maps.IdMessage{ + mapResponse, err := svc.Maps.Get(ctx, &maps.IdMessage{ ID: params.MapID, }) if err != nil { diff --git a/pkg/service/service.go b/pkg/service/service.go index 2114850..25f9215 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -6,6 +6,7 @@ import ( "fmt" "git.itzana.me/strafesnet/go-grpc/maps" + "git.itzana.me/strafesnet/go-grpc/users" "git.itzana.me/strafesnet/maps-service/pkg/api" "git.itzana.me/strafesnet/maps-service/pkg/datastore" "github.com/nats-io/nats.go" @@ -32,7 +33,8 @@ var ( type Service struct { DB datastore.Datastore Nats nats.JetStreamContext - Client maps.MapsServiceClient + Maps maps.MapsServiceClient + Users users.UsersServiceClient } // NewError creates *ErrorStatusCode from error returned by handler. diff --git a/pkg/service/submissions.go b/pkg/service/submissions.go index c1ce44c..955f5eb 100644 --- a/pkg/service/submissions.go +++ b/pkg/service/submissions.go @@ -1061,7 +1061,7 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas date := request[i].Date.Unix() var GameID = int32(submission.GameID) // create each map with go-grpc - _, err := svc.Client.Create(ctx, &maps.MapRequest{ + _, err := svc.Maps.Create(ctx, &maps.MapRequest{ ID: int64(submission.UploadedAssetID), DisplayName: &submission.DisplayName, Creator: &submission.Creator, -- 2.49.1