Skip to content

Commit ab95c3d

Browse files
committed
feat: semi-sketchy safeguards for editing a map world during/after verification
1 parent 705fdda commit ab95c3d

3 files changed

Lines changed: 54 additions & 6 deletions

File tree

api/mapsV3/intnl/openapi.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ paths:
159159
in: path
160160
required: true
161161
schema: { type: string }
162+
- name: loadTime
163+
description: Unix timestamp (millis) when the world was loaded
164+
in: query
165+
required: false
166+
schema: { type: integer }
162167
requestBody:
163168
$ref: '#/components/requestBodies/MapWorldDataRequest'
164169
responses:

api/mapsV3/intnl/server.gen.go

Lines changed: 24 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/mapsV3/intnl/server_map.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,31 @@ func (s *server) GetMapWorld(ctx context.Context, request GetMapWorldRequestObje
503503
}
504504

505505
func (s *server) UpdateMapWorld(ctx context.Context, request UpdateMapWorldRequestObject) (UpdateMapWorldResponseObject, error) {
506-
err := s.objectClient.UploadStream(ctx, request.MapId, request.Body)
506+
m, err := s.store.GetMapById(ctx, request.MapId)
507+
if errors.Is(err, mapdb.ErrNoRows) {
508+
return MapNotFoundResponse{}, nil
509+
} else if err != nil {
510+
return nil, fmt.Errorf("failed to fetch map: %w", err)
511+
}
512+
513+
// Kind of a hacky solution we should probably have some fancier solution in the future.
514+
// This is a last line of defense for not updating a map during or after verification if someone
515+
// manages to stay in an edit world during that period.
516+
// If the map is currently being verified, never allow it to be saved
517+
if m.Verification != nil && *m.Verification == int64(model.VerificationPending) {
518+
// Note: this exacerbates a race condition on exiting/saving a map -> starting to verify it.
519+
// If another builder is in the map as you begin verification they will be kicked, but the kick-save
520+
// may occur before the verification status is updated. In that case changes since the last autosave
521+
// will be lost.
522+
// For now we can accept this, and always save when the owner of the map leaves as a stop-gap.
523+
return nil, fmt.Errorf("map is currently being verified, cannot save")
524+
}
525+
// If the map is now published and the world was loaded prior to the publish date, never allow it to be saved
526+
if m.PublishedAt != nil && request.Params.LoadTime != nil && int64(*request.Params.LoadTime) < (*m.PublishedAt).UnixMilli() {
527+
return nil, fmt.Errorf("map was published after world load, cannot save")
528+
}
529+
530+
err = s.objectClient.UploadStream(ctx, request.MapId, request.Body)
507531
return UpdateMapWorld200Response{}, err
508532
}
509533

0 commit comments

Comments
 (0)