Revert "Merge pull request 'Convert Validator API to gRPC' (#239) from staging into master" #243

Merged
Quaternions merged 1 commits from undo into master 2025-07-23 04:20:06 +00:00
60 changed files with 20178 additions and 1174 deletions

195
Cargo.lock generated
View File

@@ -54,12 +54,6 @@ dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "arrayref"
version = "0.3.9"
@@ -108,17 +102,6 @@ dependencies = [
"url",
]
[[package]]
name = "async-trait"
version = "0.1.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
@@ -131,51 +114,6 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "axum"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5"
dependencies = [
"axum-core",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"sync_wrapper",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "axum-core"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"rustversion",
"sync_wrapper",
"tower-layer",
"tower-service",
]
[[package]]
name = "backtrace"
version = "0.3.75"
@@ -448,12 +386,6 @@ dependencies = [
"subtle",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encoding_rs"
version = "0.8.35"
@@ -730,12 +662,6 @@ version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "httpdate"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "1.6.0"
@@ -749,7 +675,6 @@ dependencies = [
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"smallvec",
@@ -773,19 +698,6 @@ dependencies = [
"tower-service",
]
[[package]]
name = "hyper-timeout"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
dependencies = [
"hyper",
"hyper-util",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
@@ -985,15 +897,6 @@ dependencies = [
"serde",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.15"
@@ -1115,20 +1018,13 @@ dependencies = [
"rbx_dom_weak",
"rbx_reflection_database",
"rbx_xml",
"rust-grpc",
"serde",
"serde_json",
"siphasher",
"submissions-api",
"tokio",
"tonic",
]
[[package]]
name = "matchit"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]]
name = "memchr"
version = "2.7.5"
@@ -1436,39 +1332,6 @@ dependencies = [
"syn",
]
[[package]]
name = "prost"
version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
dependencies = [
"bytes",
"prost-derive",
]
[[package]]
name = "prost-derive"
version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
dependencies = [
"anyhow",
"itertools",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "prost-types"
version = "0.13.5-serde3"
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
checksum = "e42128b6e3a6655aa5f72ac65a33848a512eb9b23e98986adc4bbe6559ea88ce"
dependencies = [
"prost",
"serde",
]
[[package]]
name = "quote"
version = "1.0.40"
@@ -1727,18 +1590,6 @@ dependencies = [
"serde",
]
[[package]]
name = "rust-grpc"
version = "1.3.0"
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
checksum = "23dc6efbef932befc29c64b9484be3686c97217f6197a91c2028c2eeee022f46"
dependencies = [
"prost",
"prost-types",
"serde",
"tonic",
]
[[package]]
name = "rustc-demangle"
version = "0.1.25"
@@ -2237,17 +2088,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.15"
@@ -2282,35 +2122,6 @@ dependencies = [
"webpki-roots 0.26.11",
]
[[package]]
name = "tonic"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9"
dependencies = [
"async-trait",
"axum",
"base64 0.22.1",
"bytes",
"h2",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-timeout",
"hyper-util",
"percent-encoding",
"pin-project",
"prost",
"socket2",
"tokio",
"tokio-stream",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower"
version = "0.5.2"
@@ -2319,15 +2130,11 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"indexmap",
"pin-project-lite",
"slab",
"sync_wrapper",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]

View File

@@ -1,3 +1,4 @@
package main
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target pkg/api --clean openapi.yaml
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target pkg/internal --clean openapi-internal.yaml

4
go.mod
View File

@@ -5,7 +5,7 @@ go 1.22
toolchain go1.23.3
require (
git.itzana.me/strafesnet/go-grpc v0.0.0-20250719033306-150dea07cf00
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9
github.com/dchest/siphash v1.2.3
github.com/go-faster/errors v0.7.1
@@ -53,7 +53,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/segmentio/asm v1.2.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
golang.org/x/net v0.25.0 // indirect

4
go.sum
View File

@@ -1,7 +1,7 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
git.itzana.me/strafesnet/go-grpc v0.0.0-20250719033306-150dea07cf00 h1:L9HiJzMrXCKZhZz+RyUr5RXdMcGQMU85aap6L+QQDZ0=
git.itzana.me/strafesnet/go-grpc v0.0.0-20250719033306-150dea07cf00/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7 h1:5XzWd3ZZjSw1M60IfHuILty2vRPBYiqM0FZ+E7uHCi8=
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9 h1:7lU6jyR7S7Rhh1dnUp7GyIRHUTBXZagw8F4n4hOyxLw=
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9/go.mod h1:uyYerSieEt4v0MJCdPLppG0LtJ4Yj035vuTetWGsxjY=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=

953
openapi-internal.yaml Normal file
View File

@@ -0,0 +1,953 @@
openapi: 3.1.0
info:
title: StrafesNET Internal - OpenAPI 3.1
description: Internal operations inaccessible from the public internet.
version: 0.1.0
tags:
- name: Mapfixes
description: Mapfix operations
- name: Operations
description: Long-running operations
- name: Scripts
description: Script operations
- name: ScriptPolicy
description: Script policy operations
- name: Submissions
description: Submission operations
paths:
/mapfixes:
post:
summary: Create a mapfix
operationId: createMapfix
tags:
- Mapfixes
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MapfixCreate'
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/MapfixID"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/validated-model:
post:
summary: Update validated model
operationId: updateMapfixValidatedModel
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
- name: ValidatedModelID
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: ValidatedModelVersion
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/error:
post:
summary: Validator posts an error to the audit log
operationId: createMapfixAuditError
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
- name: ErrorMessage
in: query
required: true
schema:
type: string
minLength: 0
maxLength: 4096
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/checklist:
post:
summary: Validator posts a checklist to the audit log
operationId: createMapfixAuditCheckList
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CheckList'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-submitted:
post:
summary: (Internal endpoint) Role Validator changes status from Submitting -> Submitted
operationId: actionMapfixSubmitted
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
- name: ModelVersion
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: DisplayName
in: query
required: true
schema:
type: string
maxLength: 128
- name: Creator
in: query
required: true
schema:
type: string
maxLength: 128
- name: GameID
in: query
required: true
schema:
type: integer
format: int32
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-request-changes:
post:
summary: (Internal endpoint) Role Validator changes status from Submitting -> ChangesRequested
operationId: actionMapfixRequestChanges
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-validated:
post:
summary: (Internal endpoint) Role Validator changes status from Validating -> Validated
operationId: actionMapfixValidated
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-failed:
post:
summary: (Internal endpoint) Role Validator changes status from Validating -> Accepted
operationId: actionMapfixAccepted
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-uploaded:
post:
summary: (Internal endpoint) Role Validator changes status from Uploading -> Uploaded
operationId: actionMapfixUploaded
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/operations/{OperationID}/status/operation-failed:
post:
summary: (Internal endpoint) Fail an operation and write a StatusMessage
operationId: actionOperationFailed
tags:
- Operations
parameters:
- $ref: '#/components/parameters/OperationID'
- name: StatusMessage
in: query
required: true
schema:
type: string
minLength: 0
maxLength: 4096
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions:
post:
summary: Create a new submission
operationId: createSubmission
tags:
- Submissions
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SubmissionCreate'
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/SubmissionID"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/validated-model:
post:
summary: Update validated model
operationId: updateSubmissionValidatedModel
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: ValidatedModelID
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: ValidatedModelVersion
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/error:
post:
summary: Validator posts an error to the audit log
operationId: createSubmissionAuditError
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: ErrorMessage
in: query
required: true
schema:
type: string
minLength: 0
maxLength: 4096
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/checklist:
post:
summary: Validator posts a checklist to the audit log
operationId: createSubmissionAuditCheckList
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CheckList'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-submitted:
post:
summary: (Internal endpoint) Role Validator changes status from Submitting -> Submitted
operationId: actionSubmissionSubmitted
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: ModelVersion
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: DisplayName
in: query
required: true
schema:
type: string
maxLength: 128
- name: Creator
in: query
required: true
schema:
type: string
maxLength: 128
- name: GameID
in: query
required: true
schema:
type: integer
format: int32
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-request-changes:
post:
summary: (Internal endpoint) Role Validator changes status from Submitting -> ChangesRequested
operationId: actionSubmissionRequestChanges
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-validated:
post:
summary: (Internal endpoint) Role Validator changes status from Validating -> Validated
operationId: actionSubmissionValidated
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-failed:
post:
summary: (Internal endpoint) Role Validator changes status from Validating -> Accepted
operationId: actionSubmissionAccepted
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-uploaded:
post:
summary: (Internal endpoint) Role Validator changes status from Uploading -> Uploaded
operationId: actionSubmissionUploaded
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: UploadedAssetID
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/script-policy:
get:
summary: Get list of script policies
operationId: listScriptPolicy
tags:
- ScriptPolicy
parameters:
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/Limit"
- name: FromScriptHash
in: query
schema:
type: string
minLength: 16
maxLength: 16
- name: ToScriptID
in: query
schema:
type: integer
format: int64
minimum: 0
- name: Policy
in: query
schema:
type: integer
format: int32
minimum: 0
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ScriptPolicy"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a new script policy
operationId: createScriptPolicy
tags:
- ScriptPolicy
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptPolicyCreate'
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/ScriptPolicyID"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/scripts:
get:
summary: Get list of scripts
operationId: listScripts
tags:
- Scripts
parameters:
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/Limit"
- name: Hash
in: query
schema:
type: string
minLength: 16
maxLength: 16
- name: Name
in: query
schema:
type: string
maxLength: 128
- name: Source
in: query
schema:
type: string
maxLength: 1048576
- name: ResourceType
in: query
schema:
type: integer
format: int32
minimum: 0
- name: ResourceID
in: query
schema:
type: integer
format: int64
minimum: 0
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Script"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a new script
operationId: createScript
tags:
- Scripts
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptCreate'
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/ScriptID"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/scripts/{ScriptID}:
get:
summary: Get the specified script by ID
operationId: getScript
tags:
- Scripts
parameters:
- $ref: '#/components/parameters/ScriptID'
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/Script"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
parameters:
MapfixID:
name: MapfixID
in: path
required: true
description: The unique identifier for a submission.
schema:
type: integer
format: int64
minimum: 0
OperationID:
name: OperationID
in: path
required: true
description: The unique identifier for a long-running operation.
schema:
type: integer
format: int32
minimum: 0
SubmissionID:
name: SubmissionID
in: path
required: true
description: The unique identifier for a submission.
schema:
type: integer
format: int64
minimum: 0
ScriptID:
name: ScriptID
in: path
required: true
description: The unique identifier for a script.
schema:
type: integer
format: int64
minimum: 0
Page:
name: Page
in: query
required: true
schema:
type: integer
format: int32
minimum: 1
Limit:
name: Limit
in: query
required: true
schema:
type: integer
format: int32
minimum: 1
maximum: 100
schemas:
MapfixID:
required:
- MapfixID
type: object
properties:
MapfixID:
type: integer
format: int64
minimum: 0
SubmissionID:
required:
- SubmissionID
type: object
properties:
SubmissionID:
type: integer
format: int64
minimum: 0
ScriptID:
required:
- ScriptID
type: object
properties:
ScriptID:
type: integer
format: int64
minimum: 0
ScriptPolicyID:
required:
- ScriptPolicyID
type: object
properties:
ScriptPolicyID:
type: integer
format: int64
minimum: 0
MapfixCreate:
required:
- OperationID
- AssetOwner
- DisplayName
- Creator
- GameID
- AssetID
- AssetVersion
- TargetAssetID
- Description
type: object
properties:
OperationID:
type: integer
format: int32
minimum: 0
AssetOwner:
type: integer
format: int64
minimum: 0
DisplayName:
type: string
maxLength: 128
Creator:
type: string
maxLength: 128
GameID:
type: integer
format: int32
minimum: 0
AssetID:
type: integer
format: int64
minimum: 0
AssetVersion:
type: integer
format: int64
minimum: 0
TargetAssetID:
type: integer
format: int64
minimum: 0
Description:
type: string
maxLength: 256
SubmissionCreate:
required:
- OperationID
- AssetOwner
- DisplayName
- Creator
- GameID
- AssetID
- AssetVersion
- Status
- Roles
type: object
properties:
OperationID:
type: integer
format: int32
minimum: 0
AssetOwner:
type: integer
format: int64
minimum: 0
DisplayName:
type: string
maxLength: 128
Creator:
type: string
maxLength: 128
GameID:
type: integer
format: int32
minimum: 0
AssetID:
type: integer
format: int64
minimum: 0
AssetVersion:
type: integer
format: int64
minimum: 0
Status:
type: integer
format: uint32
minimum: 0
maximum: 9
Roles:
type: integer
format: uint32
Script:
required:
- ID
- Name
- Hash
- Source
- ResourceType
- ResourceID
type: object
properties:
ID:
type: integer
format: int64
minimum: 0
Name:
type: string
maxLength: 128
Hash:
type: string
minLength: 16
maxLength: 16
Source:
type: string
maxLength: 1048576
ResourceType:
type: integer
format: int32
minimum: 0
ResourceID:
type: integer
format: int64
minimum: 0
ScriptCreate:
required:
- Name
- Source
- ResourceType
# - ResourceID
type: object
properties:
Name:
type: string
maxLength: 128
Source:
type: string
maxLength: 1048576
ResourceType:
type: integer
format: int32
minimum: 0
ResourceID:
type: integer
format: int64
minimum: 0
ScriptPolicy:
required:
- ID
- FromScriptHash
- ToScriptID
- Policy
type: object
properties:
ID:
type: integer
format: int64
minimum: 0
FromScriptHash:
type: string
minLength: 16
maxLength: 16
ToScriptID:
type: integer
format: int64
minimum: 0
Policy:
type: integer
format: int32
minimum: 0
ScriptPolicyCreate:
required:
- FromScriptID
- ToScriptID
- Policy
type: object
properties:
FromScriptID:
type: integer
format: int64
minimum: 0
ToScriptID:
type: integer
format: int64
minimum: 0
Policy:
type: integer
format: int32
minimum: 0
Check:
required:
- Name
- Summary
- Passed
type: object
properties:
Name:
type: string
maxLength: 128
Summary:
type: string
maxLength: 4096
Passed:
type: boolean
CheckList:
type: array
items:
$ref: "#/components/schemas/Check"
Error:
description: Represents error object
type: object
properties:
code:
type: integer
format: int64
minimum: 0
message:
type: string
required:
- code
- message

View File

@@ -2,19 +2,18 @@ package cmds
import (
"fmt"
"net"
"net/http"
"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/go-grpc/validator"
"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"
"git.itzana.me/strafesnet/maps-service/pkg/roblox"
"git.itzana.me/strafesnet/maps-service/pkg/service"
"git.itzana.me/strafesnet/maps-service/pkg/validator_controller"
"git.itzana.me/strafesnet/maps-service/pkg/web_api"
"git.itzana.me/strafesnet/maps-service/pkg/service"
"git.itzana.me/strafesnet/maps-service/pkg/service_internal"
"github.com/nats-io/nats.go"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
@@ -160,31 +159,18 @@ func serve(ctx *cli.Context) error {
log.WithError(err).Fatal("failed to initialize api server")
}
grpcServer := grpc.NewServer()
svc_internal := service_internal.NewService(&svc_inner)
mapfix_controller := validator_controller.NewMapfixesController(&svc_inner)
operation_controller := validator_controller.NewOperationsController(&svc_inner)
script_controller := validator_controller.NewScriptsController(&svc_inner)
script_policy_controller := validator_controller.NewScriptPolicyController(&svc_inner)
submission_controller := validator_controller.NewSubmissionsController(&svc_inner)
validator.RegisterValidatorMapfixServiceServer(grpcServer,&mapfix_controller)
validator.RegisterValidatorOperationServiceServer(grpcServer,&operation_controller)
validator.RegisterValidatorScriptServiceServer(grpcServer,&script_controller)
validator.RegisterValidatorScriptPolicyServiceServer(grpcServer,&script_policy_controller)
validator.RegisterValidatorSubmissionServiceServer(grpcServer,&submission_controller)
port := ctx.Int("port-internal")
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
srv_internal, err := internal.NewServer(&svc_internal, internal.WithPathPrefix("/v1"))
if err != nil {
log.WithField("error", err).Fatalln("failed to net.Listen")
log.WithError(err).Fatal("failed to initialize api server")
}
// Channel to collect errors
errChan := make(chan error, 2)
// First server
go func(errChan chan error) {
errChan <- grpcServer.Serve(lis)
errChan <- http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port-internal")), srv_internal)
}(errChan)
// Second server

283
pkg/internal/oas_cfg_gen.go Normal file
View File

@@ -0,0 +1,283 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/trace"
ht "github.com/ogen-go/ogen/http"
"github.com/ogen-go/ogen/middleware"
"github.com/ogen-go/ogen/ogenerrors"
"github.com/ogen-go/ogen/otelogen"
)
var (
// Allocate option closure once.
clientSpanKind = trace.WithSpanKind(trace.SpanKindClient)
// Allocate option closure once.
serverSpanKind = trace.WithSpanKind(trace.SpanKindServer)
)
type (
optionFunc[C any] func(*C)
otelOptionFunc func(*otelConfig)
)
type otelConfig struct {
TracerProvider trace.TracerProvider
Tracer trace.Tracer
MeterProvider metric.MeterProvider
Meter metric.Meter
}
func (cfg *otelConfig) initOTEL() {
if cfg.TracerProvider == nil {
cfg.TracerProvider = otel.GetTracerProvider()
}
if cfg.MeterProvider == nil {
cfg.MeterProvider = otel.GetMeterProvider()
}
cfg.Tracer = cfg.TracerProvider.Tracer(otelogen.Name,
trace.WithInstrumentationVersion(otelogen.SemVersion()),
)
cfg.Meter = cfg.MeterProvider.Meter(otelogen.Name,
metric.WithInstrumentationVersion(otelogen.SemVersion()),
)
}
// ErrorHandler is error handler.
type ErrorHandler = ogenerrors.ErrorHandler
type serverConfig struct {
otelConfig
NotFound http.HandlerFunc
MethodNotAllowed func(w http.ResponseWriter, r *http.Request, allowed string)
ErrorHandler ErrorHandler
Prefix string
Middleware Middleware
MaxMultipartMemory int64
}
// ServerOption is server config option.
type ServerOption interface {
applyServer(*serverConfig)
}
var _ ServerOption = (optionFunc[serverConfig])(nil)
func (o optionFunc[C]) applyServer(c *C) {
o(c)
}
var _ ServerOption = (otelOptionFunc)(nil)
func (o otelOptionFunc) applyServer(c *serverConfig) {
o(&c.otelConfig)
}
func newServerConfig(opts ...ServerOption) serverConfig {
cfg := serverConfig{
NotFound: http.NotFound,
MethodNotAllowed: func(w http.ResponseWriter, r *http.Request, allowed string) {
status := http.StatusMethodNotAllowed
if r.Method == "OPTIONS" {
w.Header().Set("Access-Control-Allow-Methods", allowed)
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
status = http.StatusNoContent
} else {
w.Header().Set("Allow", allowed)
}
w.WriteHeader(status)
},
ErrorHandler: ogenerrors.DefaultErrorHandler,
Middleware: nil,
MaxMultipartMemory: 32 << 20, // 32 MB
}
for _, opt := range opts {
opt.applyServer(&cfg)
}
cfg.initOTEL()
return cfg
}
type baseServer struct {
cfg serverConfig
requests metric.Int64Counter
errors metric.Int64Counter
duration metric.Float64Histogram
}
func (s baseServer) notFound(w http.ResponseWriter, r *http.Request) {
s.cfg.NotFound(w, r)
}
func (s baseServer) notAllowed(w http.ResponseWriter, r *http.Request, allowed string) {
s.cfg.MethodNotAllowed(w, r, allowed)
}
func (cfg serverConfig) baseServer() (s baseServer, err error) {
s = baseServer{cfg: cfg}
if s.requests, err = otelogen.ServerRequestCountCounter(s.cfg.Meter); err != nil {
return s, err
}
if s.errors, err = otelogen.ServerErrorsCountCounter(s.cfg.Meter); err != nil {
return s, err
}
if s.duration, err = otelogen.ServerDurationHistogram(s.cfg.Meter); err != nil {
return s, err
}
return s, nil
}
type clientConfig struct {
otelConfig
Client ht.Client
}
// ClientOption is client config option.
type ClientOption interface {
applyClient(*clientConfig)
}
var _ ClientOption = (optionFunc[clientConfig])(nil)
func (o optionFunc[C]) applyClient(c *C) {
o(c)
}
var _ ClientOption = (otelOptionFunc)(nil)
func (o otelOptionFunc) applyClient(c *clientConfig) {
o(&c.otelConfig)
}
func newClientConfig(opts ...ClientOption) clientConfig {
cfg := clientConfig{
Client: http.DefaultClient,
}
for _, opt := range opts {
opt.applyClient(&cfg)
}
cfg.initOTEL()
return cfg
}
type baseClient struct {
cfg clientConfig
requests metric.Int64Counter
errors metric.Int64Counter
duration metric.Float64Histogram
}
func (cfg clientConfig) baseClient() (c baseClient, err error) {
c = baseClient{cfg: cfg}
if c.requests, err = otelogen.ClientRequestCountCounter(c.cfg.Meter); err != nil {
return c, err
}
if c.errors, err = otelogen.ClientErrorsCountCounter(c.cfg.Meter); err != nil {
return c, err
}
if c.duration, err = otelogen.ClientDurationHistogram(c.cfg.Meter); err != nil {
return c, err
}
return c, nil
}
// Option is config option.
type Option interface {
ServerOption
ClientOption
}
// WithTracerProvider specifies a tracer provider to use for creating a tracer.
//
// If none is specified, the global provider is used.
func WithTracerProvider(provider trace.TracerProvider) Option {
return otelOptionFunc(func(cfg *otelConfig) {
if provider != nil {
cfg.TracerProvider = provider
}
})
}
// WithMeterProvider specifies a meter provider to use for creating a meter.
//
// If none is specified, the otel.GetMeterProvider() is used.
func WithMeterProvider(provider metric.MeterProvider) Option {
return otelOptionFunc(func(cfg *otelConfig) {
if provider != nil {
cfg.MeterProvider = provider
}
})
}
// WithClient specifies http client to use.
func WithClient(client ht.Client) ClientOption {
return optionFunc[clientConfig](func(cfg *clientConfig) {
if client != nil {
cfg.Client = client
}
})
}
// WithNotFound specifies Not Found handler to use.
func WithNotFound(notFound http.HandlerFunc) ServerOption {
return optionFunc[serverConfig](func(cfg *serverConfig) {
if notFound != nil {
cfg.NotFound = notFound
}
})
}
// WithMethodNotAllowed specifies Method Not Allowed handler to use.
func WithMethodNotAllowed(methodNotAllowed func(w http.ResponseWriter, r *http.Request, allowed string)) ServerOption {
return optionFunc[serverConfig](func(cfg *serverConfig) {
if methodNotAllowed != nil {
cfg.MethodNotAllowed = methodNotAllowed
}
})
}
// WithErrorHandler specifies error handler to use.
func WithErrorHandler(h ErrorHandler) ServerOption {
return optionFunc[serverConfig](func(cfg *serverConfig) {
if h != nil {
cfg.ErrorHandler = h
}
})
}
// WithPathPrefix specifies server path prefix.
func WithPathPrefix(prefix string) ServerOption {
return optionFunc[serverConfig](func(cfg *serverConfig) {
cfg.Prefix = prefix
})
}
// WithMiddleware specifies middlewares to use.
func WithMiddleware(m ...Middleware) ServerOption {
return optionFunc[serverConfig](func(cfg *serverConfig) {
switch len(m) {
case 0:
cfg.Middleware = nil
case 1:
cfg.Middleware = m[0]
default:
cfg.Middleware = middleware.ChainMiddlewares(m...)
}
})
}
// WithMaxMultipartMemory specifies limit of memory for storing file parts.
// File parts which can't be stored in memory will be stored on disk in temporary files.
func WithMaxMultipartMemory(max int64) ServerOption {
return optionFunc[serverConfig](func(cfg *serverConfig) {
if max > 0 {
cfg.MaxMultipartMemory = max
}
})
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1796
pkg/internal/oas_json_gen.go Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"context"
"go.opentelemetry.io/otel/attribute"
)
// Labeler is used to allow adding custom attributes to the server request metrics.
type Labeler struct {
attrs []attribute.KeyValue
}
// Add attributes to the Labeler.
func (l *Labeler) Add(attrs ...attribute.KeyValue) {
l.attrs = append(l.attrs, attrs...)
}
// AttributeSet returns the attributes added to the Labeler as an attribute.Set.
func (l *Labeler) AttributeSet() attribute.Set {
return attribute.NewSet(l.attrs...)
}
type labelerContextKey struct{}
// LabelerFromContext retrieves the Labeler from the provided context, if present.
//
// If no Labeler was found in the provided context a new, empty Labeler is returned and the second
// return value is false. In this case it is safe to use the Labeler but any attributes added to
// it will not be used.
func LabelerFromContext(ctx context.Context) (*Labeler, bool) {
if l, ok := ctx.Value(labelerContextKey{}).(*Labeler); ok {
return l, true
}
return &Labeler{}, false
}
func contextWithLabeler(ctx context.Context, l *Labeler) context.Context {
return context.WithValue(ctx, labelerContextKey{}, l)
}

View File

@@ -0,0 +1,10 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"github.com/ogen-go/ogen/middleware"
)
// Middleware is middleware type.
type Middleware = middleware.Middleware

View File

@@ -0,0 +1,33 @@
// Code generated by ogen, DO NOT EDIT.
package api
// OperationName is the ogen operation name
type OperationName = string
const (
ActionMapfixAcceptedOperation OperationName = "ActionMapfixAccepted"
ActionMapfixRequestChangesOperation OperationName = "ActionMapfixRequestChanges"
ActionMapfixSubmittedOperation OperationName = "ActionMapfixSubmitted"
ActionMapfixUploadedOperation OperationName = "ActionMapfixUploaded"
ActionMapfixValidatedOperation OperationName = "ActionMapfixValidated"
ActionOperationFailedOperation OperationName = "ActionOperationFailed"
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
ActionSubmissionRequestChangesOperation OperationName = "ActionSubmissionRequestChanges"
ActionSubmissionSubmittedOperation OperationName = "ActionSubmissionSubmitted"
ActionSubmissionUploadedOperation OperationName = "ActionSubmissionUploaded"
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
CreateMapfixOperation OperationName = "CreateMapfix"
CreateMapfixAuditCheckListOperation OperationName = "CreateMapfixAuditCheckList"
CreateMapfixAuditErrorOperation OperationName = "CreateMapfixAuditError"
CreateScriptOperation OperationName = "CreateScript"
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
CreateSubmissionOperation OperationName = "CreateSubmission"
CreateSubmissionAuditCheckListOperation OperationName = "CreateSubmissionAuditCheckList"
CreateSubmissionAuditErrorOperation OperationName = "CreateSubmissionAuditError"
GetScriptOperation OperationName = "GetScript"
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
ListScriptsOperation OperationName = "ListScripts"
UpdateMapfixValidatedModelOperation OperationName = "UpdateMapfixValidatedModel"
UpdateSubmissionValidatedModelOperation OperationName = "UpdateSubmissionValidatedModel"
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,441 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"io"
"mime"
"net/http"
"github.com/go-faster/errors"
"github.com/go-faster/jx"
"github.com/ogen-go/ogen/ogenerrors"
"github.com/ogen-go/ogen/validate"
)
func (s *Server) decodeCreateMapfixRequest(r *http.Request) (
req *MapfixCreate,
close func() error,
rerr error,
) {
var closers []func() error
close = func() error {
var merr error
// Close in reverse order, to match defer behavior.
for i := len(closers) - 1; i >= 0; i-- {
c := closers[i]
merr = errors.Join(merr, c())
}
return merr
}
defer func() {
if rerr != nil {
rerr = errors.Join(rerr, close())
}
}()
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil {
return req, close, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
if r.ContentLength == 0 {
return req, close, validate.ErrBodyRequired
}
buf, err := io.ReadAll(r.Body)
if err != nil {
return req, close, err
}
if len(buf) == 0 {
return req, close, validate.ErrBodyRequired
}
d := jx.DecodeBytes(buf)
var request MapfixCreate
if err := func() error {
if err := request.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return req, close, err
}
if err := func() error {
if err := request.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return req, close, errors.Wrap(err, "validate")
}
return &request, close, nil
default:
return req, close, validate.InvalidContentType(ct)
}
}
func (s *Server) decodeCreateMapfixAuditCheckListRequest(r *http.Request) (
req CheckList,
close func() error,
rerr error,
) {
var closers []func() error
close = func() error {
var merr error
// Close in reverse order, to match defer behavior.
for i := len(closers) - 1; i >= 0; i-- {
c := closers[i]
merr = errors.Join(merr, c())
}
return merr
}
defer func() {
if rerr != nil {
rerr = errors.Join(rerr, close())
}
}()
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil {
return req, close, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
if r.ContentLength == 0 {
return req, close, validate.ErrBodyRequired
}
buf, err := io.ReadAll(r.Body)
if err != nil {
return req, close, err
}
if len(buf) == 0 {
return req, close, validate.ErrBodyRequired
}
d := jx.DecodeBytes(buf)
var request CheckList
if err := func() error {
if err := request.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return req, close, err
}
if err := func() error {
if err := request.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return req, close, errors.Wrap(err, "validate")
}
return request, close, nil
default:
return req, close, validate.InvalidContentType(ct)
}
}
func (s *Server) decodeCreateScriptRequest(r *http.Request) (
req *ScriptCreate,
close func() error,
rerr error,
) {
var closers []func() error
close = func() error {
var merr error
// Close in reverse order, to match defer behavior.
for i := len(closers) - 1; i >= 0; i-- {
c := closers[i]
merr = errors.Join(merr, c())
}
return merr
}
defer func() {
if rerr != nil {
rerr = errors.Join(rerr, close())
}
}()
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil {
return req, close, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
if r.ContentLength == 0 {
return req, close, validate.ErrBodyRequired
}
buf, err := io.ReadAll(r.Body)
if err != nil {
return req, close, err
}
if len(buf) == 0 {
return req, close, validate.ErrBodyRequired
}
d := jx.DecodeBytes(buf)
var request ScriptCreate
if err := func() error {
if err := request.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return req, close, err
}
if err := func() error {
if err := request.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return req, close, errors.Wrap(err, "validate")
}
return &request, close, nil
default:
return req, close, validate.InvalidContentType(ct)
}
}
func (s *Server) decodeCreateScriptPolicyRequest(r *http.Request) (
req *ScriptPolicyCreate,
close func() error,
rerr error,
) {
var closers []func() error
close = func() error {
var merr error
// Close in reverse order, to match defer behavior.
for i := len(closers) - 1; i >= 0; i-- {
c := closers[i]
merr = errors.Join(merr, c())
}
return merr
}
defer func() {
if rerr != nil {
rerr = errors.Join(rerr, close())
}
}()
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil {
return req, close, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
if r.ContentLength == 0 {
return req, close, validate.ErrBodyRequired
}
buf, err := io.ReadAll(r.Body)
if err != nil {
return req, close, err
}
if len(buf) == 0 {
return req, close, validate.ErrBodyRequired
}
d := jx.DecodeBytes(buf)
var request ScriptPolicyCreate
if err := func() error {
if err := request.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return req, close, err
}
if err := func() error {
if err := request.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return req, close, errors.Wrap(err, "validate")
}
return &request, close, nil
default:
return req, close, validate.InvalidContentType(ct)
}
}
func (s *Server) decodeCreateSubmissionRequest(r *http.Request) (
req *SubmissionCreate,
close func() error,
rerr error,
) {
var closers []func() error
close = func() error {
var merr error
// Close in reverse order, to match defer behavior.
for i := len(closers) - 1; i >= 0; i-- {
c := closers[i]
merr = errors.Join(merr, c())
}
return merr
}
defer func() {
if rerr != nil {
rerr = errors.Join(rerr, close())
}
}()
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil {
return req, close, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
if r.ContentLength == 0 {
return req, close, validate.ErrBodyRequired
}
buf, err := io.ReadAll(r.Body)
if err != nil {
return req, close, err
}
if len(buf) == 0 {
return req, close, validate.ErrBodyRequired
}
d := jx.DecodeBytes(buf)
var request SubmissionCreate
if err := func() error {
if err := request.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return req, close, err
}
if err := func() error {
if err := request.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return req, close, errors.Wrap(err, "validate")
}
return &request, close, nil
default:
return req, close, validate.InvalidContentType(ct)
}
}
func (s *Server) decodeCreateSubmissionAuditCheckListRequest(r *http.Request) (
req CheckList,
close func() error,
rerr error,
) {
var closers []func() error
close = func() error {
var merr error
// Close in reverse order, to match defer behavior.
for i := len(closers) - 1; i >= 0; i-- {
c := closers[i]
merr = errors.Join(merr, c())
}
return merr
}
defer func() {
if rerr != nil {
rerr = errors.Join(rerr, close())
}
}()
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil {
return req, close, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
if r.ContentLength == 0 {
return req, close, validate.ErrBodyRequired
}
buf, err := io.ReadAll(r.Body)
if err != nil {
return req, close, err
}
if len(buf) == 0 {
return req, close, validate.ErrBodyRequired
}
d := jx.DecodeBytes(buf)
var request CheckList
if err := func() error {
if err := request.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return req, close, err
}
if err := func() error {
if err := request.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return req, close, errors.Wrap(err, "validate")
}
return request, close, nil
default:
return req, close, validate.InvalidContentType(ct)
}
}

View File

@@ -0,0 +1,96 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"bytes"
"net/http"
"github.com/go-faster/jx"
ht "github.com/ogen-go/ogen/http"
)
func encodeCreateMapfixRequest(
req *MapfixCreate,
r *http.Request,
) error {
const contentType = "application/json"
e := new(jx.Encoder)
{
req.Encode(e)
}
encoded := e.Bytes()
ht.SetBody(r, bytes.NewReader(encoded), contentType)
return nil
}
func encodeCreateMapfixAuditCheckListRequest(
req CheckList,
r *http.Request,
) error {
const contentType = "application/json"
e := new(jx.Encoder)
{
req.Encode(e)
}
encoded := e.Bytes()
ht.SetBody(r, bytes.NewReader(encoded), contentType)
return nil
}
func encodeCreateScriptRequest(
req *ScriptCreate,
r *http.Request,
) error {
const contentType = "application/json"
e := new(jx.Encoder)
{
req.Encode(e)
}
encoded := e.Bytes()
ht.SetBody(r, bytes.NewReader(encoded), contentType)
return nil
}
func encodeCreateScriptPolicyRequest(
req *ScriptPolicyCreate,
r *http.Request,
) error {
const contentType = "application/json"
e := new(jx.Encoder)
{
req.Encode(e)
}
encoded := e.Bytes()
ht.SetBody(r, bytes.NewReader(encoded), contentType)
return nil
}
func encodeCreateSubmissionRequest(
req *SubmissionCreate,
r *http.Request,
) error {
const contentType = "application/json"
e := new(jx.Encoder)
{
req.Encode(e)
}
encoded := e.Bytes()
ht.SetBody(r, bytes.NewReader(encoded), contentType)
return nil
}
func encodeCreateSubmissionAuditCheckListRequest(
req CheckList,
r *http.Request,
) error {
const contentType = "application/json"
e := new(jx.Encoder)
{
req.Encode(e)
}
encoded := e.Bytes()
ht.SetBody(r, bytes.NewReader(encoded), contentType)
return nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,266 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"net/http"
"github.com/go-faster/errors"
"github.com/go-faster/jx"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
ht "github.com/ogen-go/ogen/http"
)
func encodeActionMapfixAcceptedResponse(response *ActionMapfixAcceptedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionMapfixRequestChangesResponse(response *ActionMapfixRequestChangesNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionMapfixSubmittedResponse(response *ActionMapfixSubmittedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionMapfixUploadedResponse(response *ActionMapfixUploadedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionMapfixValidatedResponse(response *ActionMapfixValidatedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionOperationFailedResponse(response *ActionOperationFailedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionSubmissionAcceptedResponse(response *ActionSubmissionAcceptedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionSubmissionRequestChangesResponse(response *ActionSubmissionRequestChangesNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionSubmissionSubmittedResponse(response *ActionSubmissionSubmittedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionSubmissionUploadedResponse(response *ActionSubmissionUploadedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionSubmissionValidatedResponse(response *ActionSubmissionValidatedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeCreateMapfixResponse(response *MapfixID, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(201)
span.SetStatus(codes.Ok, http.StatusText(201))
e := new(jx.Encoder)
response.Encode(e)
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}
func encodeCreateMapfixAuditCheckListResponse(response *CreateMapfixAuditCheckListNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeCreateMapfixAuditErrorResponse(response *CreateMapfixAuditErrorNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeCreateScriptResponse(response *ScriptID, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(201)
span.SetStatus(codes.Ok, http.StatusText(201))
e := new(jx.Encoder)
response.Encode(e)
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}
func encodeCreateScriptPolicyResponse(response *ScriptPolicyID, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(201)
span.SetStatus(codes.Ok, http.StatusText(201))
e := new(jx.Encoder)
response.Encode(e)
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}
func encodeCreateSubmissionResponse(response *SubmissionID, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(201)
span.SetStatus(codes.Ok, http.StatusText(201))
e := new(jx.Encoder)
response.Encode(e)
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}
func encodeCreateSubmissionAuditCheckListResponse(response *CreateSubmissionAuditCheckListNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeCreateSubmissionAuditErrorResponse(response *CreateSubmissionAuditErrorNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeGetScriptResponse(response *Script, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
span.SetStatus(codes.Ok, http.StatusText(200))
e := new(jx.Encoder)
response.Encode(e)
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}
func encodeListScriptPolicyResponse(response []ScriptPolicy, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
span.SetStatus(codes.Ok, http.StatusText(200))
e := new(jx.Encoder)
e.ArrStart()
for _, elem := range response {
elem.Encode(e)
}
e.ArrEnd()
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}
func encodeListScriptsResponse(response []Script, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
span.SetStatus(codes.Ok, http.StatusText(200))
e := new(jx.Encoder)
e.ArrStart()
for _, elem := range response {
elem.Encode(e)
}
e.ArrEnd()
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}
func encodeUpdateMapfixValidatedModelResponse(response *UpdateMapfixValidatedModelNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeUpdateSubmissionValidatedModelResponse(response *UpdateSubmissionValidatedModelNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeErrorResponse(response *ErrorStatusCode, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
code := response.StatusCode
if code == 0 {
// Set default status code.
code = http.StatusOK
}
w.WriteHeader(code)
if st := http.StatusText(code); code >= http.StatusBadRequest {
span.SetStatus(codes.Error, st)
} else {
span.SetStatus(codes.Ok, st)
}
e := new(jx.Encoder)
response.Response.Encode(e)
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
if code >= http.StatusInternalServerError {
return errors.Wrapf(ht.ErrInternalServerErrorResponse, "code: %d, message: %s", code, http.StatusText(code))
}
return nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,761 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"fmt"
)
func (s *ErrorStatusCode) Error() string {
return fmt.Sprintf("code %d: %+v", s.StatusCode, s.Response)
}
// ActionMapfixAcceptedNoContent is response for ActionMapfixAccepted operation.
type ActionMapfixAcceptedNoContent struct{}
// ActionMapfixRequestChangesNoContent is response for ActionMapfixRequestChanges operation.
type ActionMapfixRequestChangesNoContent struct{}
// ActionMapfixSubmittedNoContent is response for ActionMapfixSubmitted operation.
type ActionMapfixSubmittedNoContent struct{}
// ActionMapfixUploadedNoContent is response for ActionMapfixUploaded operation.
type ActionMapfixUploadedNoContent struct{}
// ActionMapfixValidatedNoContent is response for ActionMapfixValidated operation.
type ActionMapfixValidatedNoContent struct{}
// ActionOperationFailedNoContent is response for ActionOperationFailed operation.
type ActionOperationFailedNoContent struct{}
// ActionSubmissionAcceptedNoContent is response for ActionSubmissionAccepted operation.
type ActionSubmissionAcceptedNoContent struct{}
// ActionSubmissionRequestChangesNoContent is response for ActionSubmissionRequestChanges operation.
type ActionSubmissionRequestChangesNoContent struct{}
// ActionSubmissionSubmittedNoContent is response for ActionSubmissionSubmitted operation.
type ActionSubmissionSubmittedNoContent struct{}
// ActionSubmissionUploadedNoContent is response for ActionSubmissionUploaded operation.
type ActionSubmissionUploadedNoContent struct{}
// ActionSubmissionValidatedNoContent is response for ActionSubmissionValidated operation.
type ActionSubmissionValidatedNoContent struct{}
// Ref: #/components/schemas/Check
type Check struct {
Name string `json:"Name"`
Summary string `json:"Summary"`
Passed bool `json:"Passed"`
}
// GetName returns the value of Name.
func (s *Check) GetName() string {
return s.Name
}
// GetSummary returns the value of Summary.
func (s *Check) GetSummary() string {
return s.Summary
}
// GetPassed returns the value of Passed.
func (s *Check) GetPassed() bool {
return s.Passed
}
// SetName sets the value of Name.
func (s *Check) SetName(val string) {
s.Name = val
}
// SetSummary sets the value of Summary.
func (s *Check) SetSummary(val string) {
s.Summary = val
}
// SetPassed sets the value of Passed.
func (s *Check) SetPassed(val bool) {
s.Passed = val
}
type CheckList []Check
// CreateMapfixAuditCheckListNoContent is response for CreateMapfixAuditCheckList operation.
type CreateMapfixAuditCheckListNoContent struct{}
// CreateMapfixAuditErrorNoContent is response for CreateMapfixAuditError operation.
type CreateMapfixAuditErrorNoContent struct{}
// CreateSubmissionAuditCheckListNoContent is response for CreateSubmissionAuditCheckList operation.
type CreateSubmissionAuditCheckListNoContent struct{}
// CreateSubmissionAuditErrorNoContent is response for CreateSubmissionAuditError operation.
type CreateSubmissionAuditErrorNoContent struct{}
// Represents error object.
// Ref: #/components/schemas/Error
type Error struct {
Code int64 `json:"code"`
Message string `json:"message"`
}
// GetCode returns the value of Code.
func (s *Error) GetCode() int64 {
return s.Code
}
// GetMessage returns the value of Message.
func (s *Error) GetMessage() string {
return s.Message
}
// SetCode sets the value of Code.
func (s *Error) SetCode(val int64) {
s.Code = val
}
// SetMessage sets the value of Message.
func (s *Error) SetMessage(val string) {
s.Message = val
}
// ErrorStatusCode wraps Error with StatusCode.
type ErrorStatusCode struct {
StatusCode int
Response Error
}
// GetStatusCode returns the value of StatusCode.
func (s *ErrorStatusCode) GetStatusCode() int {
return s.StatusCode
}
// GetResponse returns the value of Response.
func (s *ErrorStatusCode) GetResponse() Error {
return s.Response
}
// SetStatusCode sets the value of StatusCode.
func (s *ErrorStatusCode) SetStatusCode(val int) {
s.StatusCode = val
}
// SetResponse sets the value of Response.
func (s *ErrorStatusCode) SetResponse(val Error) {
s.Response = val
}
// Ref: #/components/schemas/MapfixCreate
type MapfixCreate struct {
OperationID int32 `json:"OperationID"`
AssetOwner int64 `json:"AssetOwner"`
DisplayName string `json:"DisplayName"`
Creator string `json:"Creator"`
GameID int32 `json:"GameID"`
AssetID int64 `json:"AssetID"`
AssetVersion int64 `json:"AssetVersion"`
TargetAssetID int64 `json:"TargetAssetID"`
Description string `json:"Description"`
}
// GetOperationID returns the value of OperationID.
func (s *MapfixCreate) GetOperationID() int32 {
return s.OperationID
}
// GetAssetOwner returns the value of AssetOwner.
func (s *MapfixCreate) GetAssetOwner() int64 {
return s.AssetOwner
}
// GetDisplayName returns the value of DisplayName.
func (s *MapfixCreate) GetDisplayName() string {
return s.DisplayName
}
// GetCreator returns the value of Creator.
func (s *MapfixCreate) GetCreator() string {
return s.Creator
}
// GetGameID returns the value of GameID.
func (s *MapfixCreate) GetGameID() int32 {
return s.GameID
}
// GetAssetID returns the value of AssetID.
func (s *MapfixCreate) GetAssetID() int64 {
return s.AssetID
}
// GetAssetVersion returns the value of AssetVersion.
func (s *MapfixCreate) GetAssetVersion() int64 {
return s.AssetVersion
}
// GetTargetAssetID returns the value of TargetAssetID.
func (s *MapfixCreate) GetTargetAssetID() int64 {
return s.TargetAssetID
}
// GetDescription returns the value of Description.
func (s *MapfixCreate) GetDescription() string {
return s.Description
}
// SetOperationID sets the value of OperationID.
func (s *MapfixCreate) SetOperationID(val int32) {
s.OperationID = val
}
// SetAssetOwner sets the value of AssetOwner.
func (s *MapfixCreate) SetAssetOwner(val int64) {
s.AssetOwner = val
}
// SetDisplayName sets the value of DisplayName.
func (s *MapfixCreate) SetDisplayName(val string) {
s.DisplayName = val
}
// SetCreator sets the value of Creator.
func (s *MapfixCreate) SetCreator(val string) {
s.Creator = val
}
// SetGameID sets the value of GameID.
func (s *MapfixCreate) SetGameID(val int32) {
s.GameID = val
}
// SetAssetID sets the value of AssetID.
func (s *MapfixCreate) SetAssetID(val int64) {
s.AssetID = val
}
// SetAssetVersion sets the value of AssetVersion.
func (s *MapfixCreate) SetAssetVersion(val int64) {
s.AssetVersion = val
}
// SetTargetAssetID sets the value of TargetAssetID.
func (s *MapfixCreate) SetTargetAssetID(val int64) {
s.TargetAssetID = val
}
// SetDescription sets the value of Description.
func (s *MapfixCreate) SetDescription(val string) {
s.Description = val
}
// Ref: #/components/schemas/MapfixID
type MapfixID struct {
MapfixID int64 `json:"MapfixID"`
}
// GetMapfixID returns the value of MapfixID.
func (s *MapfixID) GetMapfixID() int64 {
return s.MapfixID
}
// SetMapfixID sets the value of MapfixID.
func (s *MapfixID) SetMapfixID(val int64) {
s.MapfixID = val
}
// NewOptInt32 returns new OptInt32 with value set to v.
func NewOptInt32(v int32) OptInt32 {
return OptInt32{
Value: v,
Set: true,
}
}
// OptInt32 is optional int32.
type OptInt32 struct {
Value int32
Set bool
}
// IsSet returns true if OptInt32 was set.
func (o OptInt32) IsSet() bool { return o.Set }
// Reset unsets value.
func (o *OptInt32) Reset() {
var v int32
o.Value = v
o.Set = false
}
// SetTo sets value to v.
func (o *OptInt32) SetTo(v int32) {
o.Set = true
o.Value = v
}
// Get returns value and boolean that denotes whether value was set.
func (o OptInt32) Get() (v int32, ok bool) {
if !o.Set {
return v, false
}
return o.Value, true
}
// Or returns value if set, or given parameter if does not.
func (o OptInt32) Or(d int32) int32 {
if v, ok := o.Get(); ok {
return v
}
return d
}
// NewOptInt64 returns new OptInt64 with value set to v.
func NewOptInt64(v int64) OptInt64 {
return OptInt64{
Value: v,
Set: true,
}
}
// OptInt64 is optional int64.
type OptInt64 struct {
Value int64
Set bool
}
// IsSet returns true if OptInt64 was set.
func (o OptInt64) IsSet() bool { return o.Set }
// Reset unsets value.
func (o *OptInt64) Reset() {
var v int64
o.Value = v
o.Set = false
}
// SetTo sets value to v.
func (o *OptInt64) SetTo(v int64) {
o.Set = true
o.Value = v
}
// Get returns value and boolean that denotes whether value was set.
func (o OptInt64) Get() (v int64, ok bool) {
if !o.Set {
return v, false
}
return o.Value, true
}
// Or returns value if set, or given parameter if does not.
func (o OptInt64) Or(d int64) int64 {
if v, ok := o.Get(); ok {
return v
}
return d
}
// NewOptString returns new OptString with value set to v.
func NewOptString(v string) OptString {
return OptString{
Value: v,
Set: true,
}
}
// OptString is optional string.
type OptString struct {
Value string
Set bool
}
// IsSet returns true if OptString was set.
func (o OptString) IsSet() bool { return o.Set }
// Reset unsets value.
func (o *OptString) Reset() {
var v string
o.Value = v
o.Set = false
}
// SetTo sets value to v.
func (o *OptString) SetTo(v string) {
o.Set = true
o.Value = v
}
// Get returns value and boolean that denotes whether value was set.
func (o OptString) Get() (v string, ok bool) {
if !o.Set {
return v, false
}
return o.Value, true
}
// Or returns value if set, or given parameter if does not.
func (o OptString) Or(d string) string {
if v, ok := o.Get(); ok {
return v
}
return d
}
// Ref: #/components/schemas/Script
type Script struct {
ID int64 `json:"ID"`
Name string `json:"Name"`
Hash string `json:"Hash"`
Source string `json:"Source"`
ResourceType int32 `json:"ResourceType"`
ResourceID int64 `json:"ResourceID"`
}
// GetID returns the value of ID.
func (s *Script) GetID() int64 {
return s.ID
}
// GetName returns the value of Name.
func (s *Script) GetName() string {
return s.Name
}
// GetHash returns the value of Hash.
func (s *Script) GetHash() string {
return s.Hash
}
// GetSource returns the value of Source.
func (s *Script) GetSource() string {
return s.Source
}
// GetResourceType returns the value of ResourceType.
func (s *Script) GetResourceType() int32 {
return s.ResourceType
}
// GetResourceID returns the value of ResourceID.
func (s *Script) GetResourceID() int64 {
return s.ResourceID
}
// SetID sets the value of ID.
func (s *Script) SetID(val int64) {
s.ID = val
}
// SetName sets the value of Name.
func (s *Script) SetName(val string) {
s.Name = val
}
// SetHash sets the value of Hash.
func (s *Script) SetHash(val string) {
s.Hash = val
}
// SetSource sets the value of Source.
func (s *Script) SetSource(val string) {
s.Source = val
}
// SetResourceType sets the value of ResourceType.
func (s *Script) SetResourceType(val int32) {
s.ResourceType = val
}
// SetResourceID sets the value of ResourceID.
func (s *Script) SetResourceID(val int64) {
s.ResourceID = val
}
// Ref: #/components/schemas/ScriptCreate
type ScriptCreate struct {
Name string `json:"Name"`
Source string `json:"Source"`
ResourceType int32 `json:"ResourceType"`
ResourceID OptInt64 `json:"ResourceID"`
}
// GetName returns the value of Name.
func (s *ScriptCreate) GetName() string {
return s.Name
}
// GetSource returns the value of Source.
func (s *ScriptCreate) GetSource() string {
return s.Source
}
// GetResourceType returns the value of ResourceType.
func (s *ScriptCreate) GetResourceType() int32 {
return s.ResourceType
}
// GetResourceID returns the value of ResourceID.
func (s *ScriptCreate) GetResourceID() OptInt64 {
return s.ResourceID
}
// SetName sets the value of Name.
func (s *ScriptCreate) SetName(val string) {
s.Name = val
}
// SetSource sets the value of Source.
func (s *ScriptCreate) SetSource(val string) {
s.Source = val
}
// SetResourceType sets the value of ResourceType.
func (s *ScriptCreate) SetResourceType(val int32) {
s.ResourceType = val
}
// SetResourceID sets the value of ResourceID.
func (s *ScriptCreate) SetResourceID(val OptInt64) {
s.ResourceID = val
}
// Ref: #/components/schemas/ScriptID
type ScriptID struct {
ScriptID int64 `json:"ScriptID"`
}
// GetScriptID returns the value of ScriptID.
func (s *ScriptID) GetScriptID() int64 {
return s.ScriptID
}
// SetScriptID sets the value of ScriptID.
func (s *ScriptID) SetScriptID(val int64) {
s.ScriptID = val
}
// Ref: #/components/schemas/ScriptPolicy
type ScriptPolicy struct {
ID int64 `json:"ID"`
FromScriptHash string `json:"FromScriptHash"`
ToScriptID int64 `json:"ToScriptID"`
Policy int32 `json:"Policy"`
}
// GetID returns the value of ID.
func (s *ScriptPolicy) GetID() int64 {
return s.ID
}
// GetFromScriptHash returns the value of FromScriptHash.
func (s *ScriptPolicy) GetFromScriptHash() string {
return s.FromScriptHash
}
// GetToScriptID returns the value of ToScriptID.
func (s *ScriptPolicy) GetToScriptID() int64 {
return s.ToScriptID
}
// GetPolicy returns the value of Policy.
func (s *ScriptPolicy) GetPolicy() int32 {
return s.Policy
}
// SetID sets the value of ID.
func (s *ScriptPolicy) SetID(val int64) {
s.ID = val
}
// SetFromScriptHash sets the value of FromScriptHash.
func (s *ScriptPolicy) SetFromScriptHash(val string) {
s.FromScriptHash = val
}
// SetToScriptID sets the value of ToScriptID.
func (s *ScriptPolicy) SetToScriptID(val int64) {
s.ToScriptID = val
}
// SetPolicy sets the value of Policy.
func (s *ScriptPolicy) SetPolicy(val int32) {
s.Policy = val
}
// Ref: #/components/schemas/ScriptPolicyCreate
type ScriptPolicyCreate struct {
FromScriptID int64 `json:"FromScriptID"`
ToScriptID int64 `json:"ToScriptID"`
Policy int32 `json:"Policy"`
}
// GetFromScriptID returns the value of FromScriptID.
func (s *ScriptPolicyCreate) GetFromScriptID() int64 {
return s.FromScriptID
}
// GetToScriptID returns the value of ToScriptID.
func (s *ScriptPolicyCreate) GetToScriptID() int64 {
return s.ToScriptID
}
// GetPolicy returns the value of Policy.
func (s *ScriptPolicyCreate) GetPolicy() int32 {
return s.Policy
}
// SetFromScriptID sets the value of FromScriptID.
func (s *ScriptPolicyCreate) SetFromScriptID(val int64) {
s.FromScriptID = val
}
// SetToScriptID sets the value of ToScriptID.
func (s *ScriptPolicyCreate) SetToScriptID(val int64) {
s.ToScriptID = val
}
// SetPolicy sets the value of Policy.
func (s *ScriptPolicyCreate) SetPolicy(val int32) {
s.Policy = val
}
// Ref: #/components/schemas/ScriptPolicyID
type ScriptPolicyID struct {
ScriptPolicyID int64 `json:"ScriptPolicyID"`
}
// GetScriptPolicyID returns the value of ScriptPolicyID.
func (s *ScriptPolicyID) GetScriptPolicyID() int64 {
return s.ScriptPolicyID
}
// SetScriptPolicyID sets the value of ScriptPolicyID.
func (s *ScriptPolicyID) SetScriptPolicyID(val int64) {
s.ScriptPolicyID = val
}
// Ref: #/components/schemas/SubmissionCreate
type SubmissionCreate struct {
OperationID int32 `json:"OperationID"`
AssetOwner int64 `json:"AssetOwner"`
DisplayName string `json:"DisplayName"`
Creator string `json:"Creator"`
GameID int32 `json:"GameID"`
AssetID int64 `json:"AssetID"`
AssetVersion int64 `json:"AssetVersion"`
Status uint32 `json:"Status"`
Roles uint32 `json:"Roles"`
}
// GetOperationID returns the value of OperationID.
func (s *SubmissionCreate) GetOperationID() int32 {
return s.OperationID
}
// GetAssetOwner returns the value of AssetOwner.
func (s *SubmissionCreate) GetAssetOwner() int64 {
return s.AssetOwner
}
// GetDisplayName returns the value of DisplayName.
func (s *SubmissionCreate) GetDisplayName() string {
return s.DisplayName
}
// GetCreator returns the value of Creator.
func (s *SubmissionCreate) GetCreator() string {
return s.Creator
}
// GetGameID returns the value of GameID.
func (s *SubmissionCreate) GetGameID() int32 {
return s.GameID
}
// GetAssetID returns the value of AssetID.
func (s *SubmissionCreate) GetAssetID() int64 {
return s.AssetID
}
// GetAssetVersion returns the value of AssetVersion.
func (s *SubmissionCreate) GetAssetVersion() int64 {
return s.AssetVersion
}
// GetStatus returns the value of Status.
func (s *SubmissionCreate) GetStatus() uint32 {
return s.Status
}
// GetRoles returns the value of Roles.
func (s *SubmissionCreate) GetRoles() uint32 {
return s.Roles
}
// SetOperationID sets the value of OperationID.
func (s *SubmissionCreate) SetOperationID(val int32) {
s.OperationID = val
}
// SetAssetOwner sets the value of AssetOwner.
func (s *SubmissionCreate) SetAssetOwner(val int64) {
s.AssetOwner = val
}
// SetDisplayName sets the value of DisplayName.
func (s *SubmissionCreate) SetDisplayName(val string) {
s.DisplayName = val
}
// SetCreator sets the value of Creator.
func (s *SubmissionCreate) SetCreator(val string) {
s.Creator = val
}
// SetGameID sets the value of GameID.
func (s *SubmissionCreate) SetGameID(val int32) {
s.GameID = val
}
// SetAssetID sets the value of AssetID.
func (s *SubmissionCreate) SetAssetID(val int64) {
s.AssetID = val
}
// SetAssetVersion sets the value of AssetVersion.
func (s *SubmissionCreate) SetAssetVersion(val int64) {
s.AssetVersion = val
}
// SetStatus sets the value of Status.
func (s *SubmissionCreate) SetStatus(val uint32) {
s.Status = val
}
// SetRoles sets the value of Roles.
func (s *SubmissionCreate) SetRoles(val uint32) {
s.Roles = val
}
// Ref: #/components/schemas/SubmissionID
type SubmissionID struct {
SubmissionID int64 `json:"SubmissionID"`
}
// GetSubmissionID returns the value of SubmissionID.
func (s *SubmissionID) GetSubmissionID() int64 {
return s.SubmissionID
}
// SetSubmissionID sets the value of SubmissionID.
func (s *SubmissionID) SetSubmissionID(val int64) {
s.SubmissionID = val
}
// UpdateMapfixValidatedModelNoContent is response for UpdateMapfixValidatedModel operation.
type UpdateMapfixValidatedModelNoContent struct{}
// UpdateSubmissionValidatedModelNoContent is response for UpdateSubmissionValidatedModel operation.
type UpdateSubmissionValidatedModelNoContent struct{}

View File

@@ -0,0 +1,178 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"context"
)
// Handler handles operations described by OpenAPI v3 specification.
type Handler interface {
// ActionMapfixAccepted implements actionMapfixAccepted operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
//
// POST /mapfixes/{MapfixID}/status/validator-failed
ActionMapfixAccepted(ctx context.Context, params ActionMapfixAcceptedParams) error
// ActionMapfixRequestChanges implements actionMapfixRequestChanges operation.
//
// (Internal endpoint) Role Validator changes status from Submitting -> ChangesRequested.
//
// POST /mapfixes/{MapfixID}/status/validator-request-changes
ActionMapfixRequestChanges(ctx context.Context, params ActionMapfixRequestChangesParams) error
// ActionMapfixSubmitted implements actionMapfixSubmitted operation.
//
// (Internal endpoint) Role Validator changes status from Submitting -> Submitted.
//
// POST /mapfixes/{MapfixID}/status/validator-submitted
ActionMapfixSubmitted(ctx context.Context, params ActionMapfixSubmittedParams) error
// ActionMapfixUploaded implements actionMapfixUploaded operation.
//
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
//
// POST /mapfixes/{MapfixID}/status/validator-uploaded
ActionMapfixUploaded(ctx context.Context, params ActionMapfixUploadedParams) error
// ActionMapfixValidated implements actionMapfixValidated operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
//
// POST /mapfixes/{MapfixID}/status/validator-validated
ActionMapfixValidated(ctx context.Context, params ActionMapfixValidatedParams) error
// ActionOperationFailed implements actionOperationFailed operation.
//
// (Internal endpoint) Fail an operation and write a StatusMessage.
//
// POST /operations/{OperationID}/status/operation-failed
ActionOperationFailed(ctx context.Context, params ActionOperationFailedParams) error
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
//
// POST /submissions/{SubmissionID}/status/validator-failed
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
// ActionSubmissionRequestChanges implements actionSubmissionRequestChanges operation.
//
// (Internal endpoint) Role Validator changes status from Submitting -> ChangesRequested.
//
// POST /submissions/{SubmissionID}/status/validator-request-changes
ActionSubmissionRequestChanges(ctx context.Context, params ActionSubmissionRequestChangesParams) error
// ActionSubmissionSubmitted implements actionSubmissionSubmitted operation.
//
// (Internal endpoint) Role Validator changes status from Submitting -> Submitted.
//
// POST /submissions/{SubmissionID}/status/validator-submitted
ActionSubmissionSubmitted(ctx context.Context, params ActionSubmissionSubmittedParams) error
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
//
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
//
// POST /submissions/{SubmissionID}/status/validator-uploaded
ActionSubmissionUploaded(ctx context.Context, params ActionSubmissionUploadedParams) error
// ActionSubmissionValidated implements actionSubmissionValidated operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
//
// POST /submissions/{SubmissionID}/status/validator-validated
ActionSubmissionValidated(ctx context.Context, params ActionSubmissionValidatedParams) error
// CreateMapfix implements createMapfix operation.
//
// Create a mapfix.
//
// POST /mapfixes
CreateMapfix(ctx context.Context, req *MapfixCreate) (*MapfixID, error)
// CreateMapfixAuditCheckList implements createMapfixAuditCheckList operation.
//
// Validator posts a checklist to the audit log.
//
// POST /mapfixes/{MapfixID}/checklist
CreateMapfixAuditCheckList(ctx context.Context, req CheckList, params CreateMapfixAuditCheckListParams) error
// CreateMapfixAuditError implements createMapfixAuditError operation.
//
// Validator posts an error to the audit log.
//
// POST /mapfixes/{MapfixID}/error
CreateMapfixAuditError(ctx context.Context, params CreateMapfixAuditErrorParams) error
// CreateScript implements createScript operation.
//
// Create a new script.
//
// POST /scripts
CreateScript(ctx context.Context, req *ScriptCreate) (*ScriptID, error)
// CreateScriptPolicy implements createScriptPolicy operation.
//
// Create a new script policy.
//
// POST /script-policy
CreateScriptPolicy(ctx context.Context, req *ScriptPolicyCreate) (*ScriptPolicyID, error)
// CreateSubmission implements createSubmission operation.
//
// Create a new submission.
//
// POST /submissions
CreateSubmission(ctx context.Context, req *SubmissionCreate) (*SubmissionID, error)
// CreateSubmissionAuditCheckList implements createSubmissionAuditCheckList operation.
//
// Validator posts a checklist to the audit log.
//
// POST /submissions/{SubmissionID}/checklist
CreateSubmissionAuditCheckList(ctx context.Context, req CheckList, params CreateSubmissionAuditCheckListParams) error
// CreateSubmissionAuditError implements createSubmissionAuditError operation.
//
// Validator posts an error to the audit log.
//
// POST /submissions/{SubmissionID}/error
CreateSubmissionAuditError(ctx context.Context, params CreateSubmissionAuditErrorParams) error
// GetScript implements getScript operation.
//
// Get the specified script by ID.
//
// GET /scripts/{ScriptID}
GetScript(ctx context.Context, params GetScriptParams) (*Script, error)
// ListScriptPolicy implements listScriptPolicy operation.
//
// Get list of script policies.
//
// GET /script-policy
ListScriptPolicy(ctx context.Context, params ListScriptPolicyParams) ([]ScriptPolicy, error)
// ListScripts implements listScripts operation.
//
// Get list of scripts.
//
// GET /scripts
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
// UpdateMapfixValidatedModel implements updateMapfixValidatedModel operation.
//
// Update validated model.
//
// POST /mapfixes/{MapfixID}/validated-model
UpdateMapfixValidatedModel(ctx context.Context, params UpdateMapfixValidatedModelParams) error
// UpdateSubmissionValidatedModel implements updateSubmissionValidatedModel operation.
//
// Update validated model.
//
// POST /submissions/{SubmissionID}/validated-model
UpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) error
// NewError creates *ErrorStatusCode from error returned by handler.
//
// Used for common default response.
NewError(ctx context.Context, err error) *ErrorStatusCode
}
// Server implements http server based on OpenAPI v3 specification and
// calls Handler to handle requests.
type Server struct {
h Handler
baseServer
}
// NewServer creates new Server.
func NewServer(h Handler, opts ...ServerOption) (*Server, error) {
s, err := newServerConfig(opts...).baseServer()
if err != nil {
return nil, err
}
return &Server{
h: h,
baseServer: s,
}, nil
}

View File

@@ -0,0 +1,238 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"context"
ht "github.com/ogen-go/ogen/http"
)
// UnimplementedHandler is no-op Handler which returns http.ErrNotImplemented.
type UnimplementedHandler struct{}
var _ Handler = UnimplementedHandler{}
// ActionMapfixAccepted implements actionMapfixAccepted operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
//
// POST /mapfixes/{MapfixID}/status/validator-failed
func (UnimplementedHandler) ActionMapfixAccepted(ctx context.Context, params ActionMapfixAcceptedParams) error {
return ht.ErrNotImplemented
}
// ActionMapfixRequestChanges implements actionMapfixRequestChanges operation.
//
// (Internal endpoint) Role Validator changes status from Submitting -> ChangesRequested.
//
// POST /mapfixes/{MapfixID}/status/validator-request-changes
func (UnimplementedHandler) ActionMapfixRequestChanges(ctx context.Context, params ActionMapfixRequestChangesParams) error {
return ht.ErrNotImplemented
}
// ActionMapfixSubmitted implements actionMapfixSubmitted operation.
//
// (Internal endpoint) Role Validator changes status from Submitting -> Submitted.
//
// POST /mapfixes/{MapfixID}/status/validator-submitted
func (UnimplementedHandler) ActionMapfixSubmitted(ctx context.Context, params ActionMapfixSubmittedParams) error {
return ht.ErrNotImplemented
}
// ActionMapfixUploaded implements actionMapfixUploaded operation.
//
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
//
// POST /mapfixes/{MapfixID}/status/validator-uploaded
func (UnimplementedHandler) ActionMapfixUploaded(ctx context.Context, params ActionMapfixUploadedParams) error {
return ht.ErrNotImplemented
}
// ActionMapfixValidated implements actionMapfixValidated operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
//
// POST /mapfixes/{MapfixID}/status/validator-validated
func (UnimplementedHandler) ActionMapfixValidated(ctx context.Context, params ActionMapfixValidatedParams) error {
return ht.ErrNotImplemented
}
// ActionOperationFailed implements actionOperationFailed operation.
//
// (Internal endpoint) Fail an operation and write a StatusMessage.
//
// POST /operations/{OperationID}/status/operation-failed
func (UnimplementedHandler) ActionOperationFailed(ctx context.Context, params ActionOperationFailedParams) error {
return ht.ErrNotImplemented
}
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
//
// POST /submissions/{SubmissionID}/status/validator-failed
func (UnimplementedHandler) ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error {
return ht.ErrNotImplemented
}
// ActionSubmissionRequestChanges implements actionSubmissionRequestChanges operation.
//
// (Internal endpoint) Role Validator changes status from Submitting -> ChangesRequested.
//
// POST /submissions/{SubmissionID}/status/validator-request-changes
func (UnimplementedHandler) ActionSubmissionRequestChanges(ctx context.Context, params ActionSubmissionRequestChangesParams) error {
return ht.ErrNotImplemented
}
// ActionSubmissionSubmitted implements actionSubmissionSubmitted operation.
//
// (Internal endpoint) Role Validator changes status from Submitting -> Submitted.
//
// POST /submissions/{SubmissionID}/status/validator-submitted
func (UnimplementedHandler) ActionSubmissionSubmitted(ctx context.Context, params ActionSubmissionSubmittedParams) error {
return ht.ErrNotImplemented
}
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
//
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
//
// POST /submissions/{SubmissionID}/status/validator-uploaded
func (UnimplementedHandler) ActionSubmissionUploaded(ctx context.Context, params ActionSubmissionUploadedParams) error {
return ht.ErrNotImplemented
}
// ActionSubmissionValidated implements actionSubmissionValidated operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
//
// POST /submissions/{SubmissionID}/status/validator-validated
func (UnimplementedHandler) ActionSubmissionValidated(ctx context.Context, params ActionSubmissionValidatedParams) error {
return ht.ErrNotImplemented
}
// CreateMapfix implements createMapfix operation.
//
// Create a mapfix.
//
// POST /mapfixes
func (UnimplementedHandler) CreateMapfix(ctx context.Context, req *MapfixCreate) (r *MapfixID, _ error) {
return r, ht.ErrNotImplemented
}
// CreateMapfixAuditCheckList implements createMapfixAuditCheckList operation.
//
// Validator posts a checklist to the audit log.
//
// POST /mapfixes/{MapfixID}/checklist
func (UnimplementedHandler) CreateMapfixAuditCheckList(ctx context.Context, req CheckList, params CreateMapfixAuditCheckListParams) error {
return ht.ErrNotImplemented
}
// CreateMapfixAuditError implements createMapfixAuditError operation.
//
// Validator posts an error to the audit log.
//
// POST /mapfixes/{MapfixID}/error
func (UnimplementedHandler) CreateMapfixAuditError(ctx context.Context, params CreateMapfixAuditErrorParams) error {
return ht.ErrNotImplemented
}
// CreateScript implements createScript operation.
//
// Create a new script.
//
// POST /scripts
func (UnimplementedHandler) CreateScript(ctx context.Context, req *ScriptCreate) (r *ScriptID, _ error) {
return r, ht.ErrNotImplemented
}
// CreateScriptPolicy implements createScriptPolicy operation.
//
// Create a new script policy.
//
// POST /script-policy
func (UnimplementedHandler) CreateScriptPolicy(ctx context.Context, req *ScriptPolicyCreate) (r *ScriptPolicyID, _ error) {
return r, ht.ErrNotImplemented
}
// CreateSubmission implements createSubmission operation.
//
// Create a new submission.
//
// POST /submissions
func (UnimplementedHandler) CreateSubmission(ctx context.Context, req *SubmissionCreate) (r *SubmissionID, _ error) {
return r, ht.ErrNotImplemented
}
// CreateSubmissionAuditCheckList implements createSubmissionAuditCheckList operation.
//
// Validator posts a checklist to the audit log.
//
// POST /submissions/{SubmissionID}/checklist
func (UnimplementedHandler) CreateSubmissionAuditCheckList(ctx context.Context, req CheckList, params CreateSubmissionAuditCheckListParams) error {
return ht.ErrNotImplemented
}
// CreateSubmissionAuditError implements createSubmissionAuditError operation.
//
// Validator posts an error to the audit log.
//
// POST /submissions/{SubmissionID}/error
func (UnimplementedHandler) CreateSubmissionAuditError(ctx context.Context, params CreateSubmissionAuditErrorParams) error {
return ht.ErrNotImplemented
}
// GetScript implements getScript operation.
//
// Get the specified script by ID.
//
// GET /scripts/{ScriptID}
func (UnimplementedHandler) GetScript(ctx context.Context, params GetScriptParams) (r *Script, _ error) {
return r, ht.ErrNotImplemented
}
// ListScriptPolicy implements listScriptPolicy operation.
//
// Get list of script policies.
//
// GET /script-policy
func (UnimplementedHandler) ListScriptPolicy(ctx context.Context, params ListScriptPolicyParams) (r []ScriptPolicy, _ error) {
return r, ht.ErrNotImplemented
}
// ListScripts implements listScripts operation.
//
// Get list of scripts.
//
// GET /scripts
func (UnimplementedHandler) ListScripts(ctx context.Context, params ListScriptsParams) (r []Script, _ error) {
return r, ht.ErrNotImplemented
}
// UpdateMapfixValidatedModel implements updateMapfixValidatedModel operation.
//
// Update validated model.
//
// POST /mapfixes/{MapfixID}/validated-model
func (UnimplementedHandler) UpdateMapfixValidatedModel(ctx context.Context, params UpdateMapfixValidatedModelParams) error {
return ht.ErrNotImplemented
}
// UpdateSubmissionValidatedModel implements updateSubmissionValidatedModel operation.
//
// Update validated model.
//
// POST /submissions/{SubmissionID}/validated-model
func (UnimplementedHandler) UpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) error {
return ht.ErrNotImplemented
}
// NewError creates *ErrorStatusCode from error returned by handler.
//
// Used for common default response.
func (UnimplementedHandler) NewError(ctx context.Context, err error) (r *ErrorStatusCode) {
r = new(ErrorStatusCode)
return r
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,12 +2,9 @@ package model
import (
"encoding/json"
"math"
"time"
)
const ValidatorUserID uint64 = uint64(math.MaxInt64)
type AuditEventType int32
// User clicked "Submit", "Accept" etc

View File

@@ -1,28 +1,16 @@
package validator_controller
package service_internal
import (
"context"
"errors"
"fmt"
"git.itzana.me/strafesnet/go-grpc/validator"
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
"git.itzana.me/strafesnet/maps-service/pkg/model"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
type Mapfixes struct {
*validator.UnimplementedValidatorMapfixServiceServer
inner *service.Service
}
func NewMapfixesController(
inner *service.Service,
) Mapfixes {
return Mapfixes{
inner: inner,
}
}
var(
// prevent two mapfixes with same asset id
ActiveMapfixStatuses = []model.MapfixStatus{
@@ -46,40 +34,35 @@ var(
// Update model following role restrictions.
//
// POST /mapfixes/{MapfixID}/validated-model
func (svc *Mapfixes) SetValidatedModel(ctx context.Context, params *validator.ValidatedModelRequest) (*validator.NullResponse, error) {
MapfixID := int64(params.ID)
func (svc *Service) UpdateMapfixValidatedModel(ctx context.Context, params internal.UpdateMapfixValidatedModelParams) error {
ValidatedModelID := uint64(params.ValidatedModelID)
ValidatedModelVersion := uint64(params.ValidatedModelVersion)
// check if Status is ChangesRequested|Submitted|UnderConstruction
update := service.NewMapfixUpdate()
update.SetValidatedAssetID(params.ValidatedModelID)
update.SetValidatedAssetVersion(params.ValidatedModelVersion)
update.SetValidatedAssetID(ValidatedModelID)
update.SetValidatedAssetVersion(ValidatedModelVersion)
// DO NOT reset completed when validated model is updated
// update.Add("completed", false)
allow_statuses := []model.MapfixStatus{model.MapfixStatusValidating}
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
err := svc.inner.UpdateMapfixIfStatus(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidating}, update)
if err != nil {
return nil, err
return err
}
event_data := model.AuditEventDataChangeValidatedModel{
ValidatedModelID: params.ValidatedModelID,
ValidatedModelVersion: params.ValidatedModelVersion,
ValidatedModelID: ValidatedModelID,
ValidatedModelVersion: ValidatedModelVersion,
}
err = svc.inner.CreateAuditEventChangeValidatedModel(
return svc.inner.CreateAuditEventChangeValidatedModel(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: MapfixID,
ID: params.MapfixID,
Type: model.ResourceMapfix,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionMapfixSubmitted invokes actionMapfixSubmitted operation.
@@ -87,8 +70,7 @@ func (svc *Mapfixes) SetValidatedModel(ctx context.Context, params *validator.Va
// Role Validator changes status from Submitting -> Submitted.
//
// POST /mapfixes/{MapfixID}/status/validator-submitted
func (svc *Mapfixes) SetStatusSubmitted(ctx context.Context, params *validator.SubmittedRequest) (*validator.NullResponse, error) {
MapfixID := int64(params.ID)
func (svc *Service) ActionMapfixSubmitted(ctx context.Context, params internal.ActionMapfixSubmittedParams) error {
// transaction
target_status := model.MapfixStatusSubmitted
update := service.NewMapfixUpdate()
@@ -98,29 +80,24 @@ func (svc *Mapfixes) SetStatusSubmitted(ctx context.Context, params *validator.S
update.SetCreator(params.Creator)
update.SetGameID(uint32(params.GameID))
allow_statuses := []model.MapfixStatus{model.MapfixStatusSubmitting}
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
err := svc.inner.UpdateMapfixIfStatus(ctx, params.MapfixID, allow_statuses, update)
if err != nil {
return nil, err
return err
}
event_data := model.AuditEventDataAction{
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: MapfixID,
ID: params.MapfixID,
Type: model.ResourceMapfix,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionMapfixRequestChanges implements actionMapfixRequestChanges operation.
@@ -128,36 +105,29 @@ func (svc *Mapfixes) SetStatusSubmitted(ctx context.Context, params *validator.S
// (Internal endpoint) Role Validator changes status from Submitting -> RequestChanges.
//
// POST /mapfixes/{MapfixID}/status/validator-request-changes
func (svc *Mapfixes) ActionMapfixRequestChanges(ctx context.Context, params *validator.MapfixID) (*validator.NullResponse, error) {
MapfixID := int64(params.ID)
func (svc *Service) ActionMapfixRequestChanges(ctx context.Context, params internal.ActionMapfixRequestChangesParams) error {
// transaction
target_status := model.MapfixStatusChangesRequested
update := service.NewMapfixUpdate()
update.SetStatusID(target_status)
allow_statuses := []model.MapfixStatus{model.MapfixStatusSubmitting}
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
err := svc.inner.UpdateMapfixIfStatus(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusSubmitting}, update)
if err != nil {
return nil, err
return err
}
event_data := model.AuditEventDataAction{
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: MapfixID,
ID: params.MapfixID,
Type: model.ResourceMapfix,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionMapfixValidate invokes actionMapfixValidate operation.
@@ -165,18 +135,11 @@ func (svc *Mapfixes) ActionMapfixRequestChanges(ctx context.Context, params *val
// Role Validator changes status from Validating -> Validated.
//
// POST /mapfixes/{MapfixID}/status/validator-validated
func (svc *Mapfixes) ActionMapfixValidated(ctx context.Context, params *validator.MapfixID) (*validator.NullResponse, error) {
MapfixID := int64(params.ID)
func (svc *Service) ActionMapfixValidated(ctx context.Context, params internal.ActionMapfixValidatedParams) error {
// transaction
update := service.NewMapfixUpdate()
update.SetStatusID(model.MapfixStatusValidated)
allow_statuses := []model.MapfixStatus{model.MapfixStatusValidating}
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
return svc.inner.UpdateMapfixIfStatus(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidating}, update)
}
// ActionMapfixAccepted implements actionMapfixAccepted operation.
@@ -184,16 +147,14 @@ func (svc *Mapfixes) ActionMapfixValidated(ctx context.Context, params *validato
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
//
// POST /mapfixes/{MapfixID}/status/validator-failed
func (svc *Mapfixes) ActionMapfixAccepted(ctx context.Context, params *validator.MapfixID) (*validator.NullResponse, error) {
MapfixID := int64(params.ID)
func (svc *Service) ActionMapfixAccepted(ctx context.Context, params internal.ActionMapfixAcceptedParams) error {
// transaction
target_status := model.MapfixStatusAcceptedUnvalidated
update := service.NewMapfixUpdate()
update.SetStatusID(target_status)
allow_statuses := []model.MapfixStatus{model.MapfixStatusValidating}
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
err := svc.inner.UpdateMapfixIfStatus(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidating}, update)
if err != nil {
return nil, err
return err
}
// push an action audit event
@@ -201,20 +162,15 @@ func (svc *Mapfixes) ActionMapfixAccepted(ctx context.Context, params *validator
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: MapfixID,
ID: params.MapfixID,
Type: model.ResourceMapfix,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionMapfixUploaded implements actionMapfixUploaded operation.
@@ -222,36 +178,29 @@ func (svc *Mapfixes) ActionMapfixAccepted(ctx context.Context, params *validator
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
//
// POST /mapfixes/{MapfixID}/status/validator-uploaded
func (svc *Mapfixes) ActionMapfixUploaded(ctx context.Context, params *validator.MapfixID) (*validator.NullResponse, error) {
MapfixID := int64(params.ID)
func (svc *Service) ActionMapfixUploaded(ctx context.Context, params internal.ActionMapfixUploadedParams) error {
// transaction
target_status := model.MapfixStatusUploaded
update := service.NewMapfixUpdate()
update.SetStatusID(target_status)
allow_statuses := []model.MapfixStatus{model.MapfixStatusUploading}
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
err := svc.inner.UpdateMapfixIfStatus(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusUploading}, update)
if err != nil {
return nil, err
return err
}
event_data := model.AuditEventDataAction{
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: MapfixID,
ID: params.MapfixID,
Type: model.ResourceMapfix,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// CreateMapfixAuditError implements createMapfixAuditError operation.
@@ -259,26 +208,20 @@ func (svc *Mapfixes) ActionMapfixUploaded(ctx context.Context, params *validator
// Post an error to the audit log
//
// POST /mapfixes/{MapfixID}/error
func (svc *Mapfixes) CreateMapfixAuditError(ctx context.Context, params *validator.AuditErrorRequest) (*validator.NullResponse, error) {
MapfixID := int64(params.ID)
func (svc *Service) CreateMapfixAuditError(ctx context.Context, params internal.CreateMapfixAuditErrorParams) (error) {
event_data := model.AuditEventDataError{
Error: params.ErrorMessage,
}
err := svc.inner.CreateAuditEventError(
return svc.inner.CreateAuditEventError(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: MapfixID,
ID: params.MapfixID,
Type: model.ResourceMapfix,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// CreateMapfixAuditCheckList implements createMapfixAuditCheckList operation.
@@ -286,11 +229,10 @@ func (svc *Mapfixes) CreateMapfixAuditError(ctx context.Context, params *validat
// Post a checklist to the audit log
//
// POST /mapfixes/{MapfixID}/checklist
func (svc *Mapfixes) CreateMapfixAuditCheckList(ctx context.Context, params *validator.AuditChecklistRequest) (*validator.NullResponse, error) {
MapfixID := int64(params.ID)
check_list := make([]model.Check, len(params.CheckList))
for i, check := range params.CheckList {
check_list[i] = model.Check{
func (svc *Service) CreateMapfixAuditCheckList(ctx context.Context, check_list internal.CheckList, params internal.CreateMapfixAuditCheckListParams) (error) {
check_list2 := make([]model.Check, len(check_list))
for i, check := range check_list {
check_list2[i] = model.Check{
Name: check.Name,
Summary: check.Summary,
Passed: check.Passed,
@@ -298,33 +240,41 @@ func (svc *Mapfixes) CreateMapfixAuditCheckList(ctx context.Context, params *val
}
event_data := model.AuditEventDataCheckList{
CheckList: check_list,
CheckList: check_list2,
}
err := svc.inner.CreateAuditEventCheckList(
return svc.inner.CreateAuditEventCheckList(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: MapfixID,
ID: params.MapfixID,
Type: model.ResourceMapfix,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// POST /mapfixes
func (svc *Mapfixes) Create(ctx context.Context, request *validator.MapfixCreate) (*validator.MapfixID, error) {
var Submitter=request.AssetOwner;
func (svc *Service) CreateMapfix(ctx context.Context, request *internal.MapfixCreate) (*internal.MapfixID, error) {
// sanitization
if request.GameID<0||
request.AssetOwner<0||
request.AssetID<0||
request.AssetVersion<0||
request.TargetAssetID<0{
return nil, ErrNegativeID
}
var GameID=uint32(request.GameID);
var Submitter=uint64(request.AssetOwner);
var AssetID=uint64(request.AssetID);
var AssetVersion=uint64(request.AssetVersion);
var TargetAssetID=uint64(request.TargetAssetID);
// Check if an active mapfix with the same asset id exists
{
filter := service.NewMapfixFilter()
filter.SetAssetID(request.AssetID)
filter.SetAssetVersion(request.AssetVersion)
filter.SetAssetID(AssetID)
filter.SetAssetVersion(AssetVersion)
filter.SetStatuses(ActiveMapfixStatuses)
active_mapfixes, err := svc.inner.ListMapfixes(ctx, filter, model.Page{
Number: 1,
@@ -338,8 +288,7 @@ func (svc *Mapfixes) Create(ctx context.Context, request *validator.MapfixCreate
}
}
OperationID := int32(request.OperationID)
operation, err := svc.inner.GetOperation(ctx, OperationID)
operation, err := svc.inner.GetOperation(ctx, request.OperationID)
if err != nil {
return nil, err
}
@@ -354,12 +303,12 @@ func (svc *Mapfixes) Create(ctx context.Context, request *validator.MapfixCreate
ID: 0,
DisplayName: request.DisplayName,
Creator: request.Creator,
GameID: request.GameID,
GameID: GameID,
Submitter: Submitter,
AssetID: request.AssetID,
AssetVersion: request.AssetVersion,
AssetID: AssetID,
AssetVersion: AssetVersion,
Completed: false,
TargetAssetID: request.TargetAssetID,
TargetAssetID: TargetAssetID,
StatusID: model.MapfixStatusUnderConstruction,
Description: request.Description,
})
@@ -369,12 +318,12 @@ func (svc *Mapfixes) Create(ctx context.Context, request *validator.MapfixCreate
// mark the operation as completed and provide the path
params := service.NewOperationCompleteParams(fmt.Sprintf("/mapfixes/%d", mapfix.ID))
err = svc.inner.CompleteOperation(ctx, OperationID, params)
err = svc.inner.CompleteOperation(ctx, request.OperationID, params)
if err != nil {
return nil, err
}
return &validator.MapfixID{
ID: uint64(mapfix.ID),
return &internal.MapfixID{
MapfixID: mapfix.ID,
}, nil
}

View File

@@ -0,0 +1,20 @@
package service_internal
import (
"context"
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
// ActionOperationFailed implements actionOperationFailed operation.
//
// Fail the specified OperationID with a StatusMessage.
//
// POST /operations/{OperationID}/status/operation-failed
func (svc *Service) ActionOperationFailed(ctx context.Context, params internal.ActionOperationFailedParams) (error) {
fail_params := service.NewOperationFailParams(
params.StatusMessage,
)
return svc.inner.FailOperation(ctx, params.OperationID, fail_params)
}

View File

@@ -0,0 +1,80 @@
package service_internal
import (
"context"
api "git.itzana.me/strafesnet/maps-service/pkg/internal"
"git.itzana.me/strafesnet/maps-service/pkg/model"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
// CreateScriptPolicy implements createScriptPolicy operation.
//
// Create a new script policy.
//
// POST /script-policy
func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolicyCreate) (*api.ScriptPolicyID, error) {
from_script, err := svc.inner.GetScript(ctx, req.FromScriptID)
if err != nil {
return nil, err
}
// the existence of ToScriptID does not need to be validated because it's checked by a foreign key constraint.
script, err := svc.inner.CreateScriptPolicy(ctx, model.ScriptPolicy{
ID: 0,
FromScriptHash: from_script.Hash,
ToScriptID: req.ToScriptID,
Policy: model.Policy(req.Policy),
})
if err != nil {
return nil, err
}
return &api.ScriptPolicyID{
ScriptPolicyID: script.ID,
}, nil
}
// ListScriptPolicy implements listScriptPolicy operation.
//
// Get list of script policies.
//
// GET /script-policy
func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptPolicyParams) ([]api.ScriptPolicy, error) {
filter := service.NewScriptPolicyFilter()
if hash_hex, ok := params.FromScriptHash.Get(); ok{
hash_parsed, err := model.HashParse(hash_hex)
if err != nil {
return nil, err
}
filter.SetFromScriptHash(int64(hash_parsed))
}
if to_script_id, to_script_id_ok := params.ToScriptID.Get(); to_script_id_ok{
filter.SetToScriptID(to_script_id)
}
if policy, policy_ok := params.Policy.Get(); policy_ok{
filter.SetPolicy(policy)
}
items, err := svc.inner.ListScriptPolicies(ctx, filter, model.Page{
Number: params.Page,
Size: params.Limit,
})
if err != nil {
return nil, err
}
var resp []api.ScriptPolicy
for _, item := range items {
resp = append(resp, api.ScriptPolicy{
ID: item.ID,
FromScriptHash: model.HashFormat(uint64(item.FromScriptHash)),
ToScriptID: item.ToScriptID,
Policy: int32(item.Policy),
})
}
return resp, nil
}

View File

@@ -0,0 +1,103 @@
package service_internal
import (
"context"
api "git.itzana.me/strafesnet/maps-service/pkg/internal"
"git.itzana.me/strafesnet/maps-service/pkg/model"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
// CreateScript implements createScript operation.
//
// Create a new script.
//
// POST /scripts
func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*api.ScriptID, error) {
script, err := svc.inner.CreateScript(ctx, model.Script{
ID: 0,
Name: req.Name,
Hash: int64(model.HashSource(req.Source)),
Source: req.Source,
ResourceType: model.ResourceType(req.ResourceType),
ResourceID: req.ResourceID.Or(0),
})
if err != nil {
return nil, err
}
return &api.ScriptID{
ScriptID: script.ID,
}, nil
}
// ListScripts implements listScripts operation.
//
// Get list of scripts.
//
// GET /scripts
func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParams) ([]api.Script, error) {
filter := service.NewScriptFilter()
if hash_hex, ok := params.Hash.Get(); ok{
hash_parsed, err := model.HashParse(hash_hex)
if err != nil {
return nil, err
}
filter.SetHash(int64(hash_parsed))
}
if name, name_ok := params.Name.Get(); name_ok{
filter.SetName(name)
}
if source, source_ok := params.Source.Get(); source_ok{
filter.SetSource(source)
}
if resource_type, resource_type_ok := params.ResourceType.Get(); resource_type_ok{
filter.SetResourceType(resource_type)
}
if resource_id, resource_id_ok := params.ResourceID.Get(); resource_id_ok{
filter.SetResourceID(resource_id)
}
items, err := svc.inner.ListScripts(ctx, filter, model.Page{
Number: params.Page,
Size: params.Limit,
})
if err != nil {
return nil, err
}
var resp []api.Script
for _, item := range items {
resp = append(resp, api.Script{
ID: item.ID,
Name: item.Name,
Hash: model.HashFormat(uint64(item.Hash)),
Source: item.Source,
ResourceType: int32(item.ResourceType),
ResourceID: item.ResourceID,
})
}
return resp, nil
}
// GetScript implements getScript operation.
//
// Get the specified script by ID.
//
// GET /scripts/{ScriptID}
func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (*api.Script, error) {
script, err := svc.inner.GetScript(ctx, params.ScriptID)
if err != nil {
return nil, err
}
return &api.Script{
ID: script.ID,
Name: script.Name,
Hash: model.HashFormat(uint64(script.Hash)),
Source: script.Source,
ResourceType: int32(script.ResourceType),
ResourceID: script.ResourceID,
}, nil
}

View File

@@ -0,0 +1,46 @@
package service_internal
import (
"context"
"errors"
"math"
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
const (
ValidtorUserID uint64 = uint64(math.MaxInt64)
)
var (
ErrNegativeID = errors.New("A negative ID was provided")
)
type Service struct {
inner *service.Service
}
func NewService(
inner *service.Service,
) Service {
return Service{
inner: inner,
}
}
// yay duplicate code
func (svc *Service) NewError(ctx context.Context, err error) *internal.ErrorStatusCode {
status := 500
if errors.Is(err, datastore.ErrNotExist) {
status = 404
}
return &internal.ErrorStatusCode{
StatusCode: status,
Response: internal.Error{
Code: int64(status),
Message: err.Error(),
},
}
}

View File

@@ -1,28 +1,16 @@
package validator_controller
package service_internal
import (
"context"
"errors"
"fmt"
"git.itzana.me/strafesnet/go-grpc/validator"
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
"git.itzana.me/strafesnet/maps-service/pkg/model"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
type Submissions struct {
*validator.UnimplementedValidatorSubmissionServiceServer
inner *service.Service
}
func NewSubmissionsController(
inner *service.Service,
) Submissions {
return Submissions{
inner: inner,
}
}
var(
// prevent two mapfixes with same asset id
ActiveSubmissionStatuses = []model.SubmissionStatus{
@@ -45,40 +33,36 @@ var(
// Update model following role restrictions.
//
// POST /submissions/{SubmissionID}/validated-model
func (svc *Submissions) SetValidatedModel(ctx context.Context, params *validator.ValidatedModelRequest) (*validator.NullResponse, error) {
SubmissionID := int64(params.ID)
func (svc *Service) UpdateSubmissionValidatedModel(ctx context.Context, params internal.UpdateSubmissionValidatedModelParams) error {
ValidatedModelID := uint64(params.ValidatedModelID)
ValidatedModelVersion := uint64(params.ValidatedModelVersion)
// check if Status is ChangesRequested|Submitted|UnderConstruction
update := service.NewSubmissionUpdate()
update.SetValidatedAssetID(params.ValidatedModelID)
update.SetValidatedAssetVersion(params.ValidatedModelVersion)
update.SetValidatedAssetID(ValidatedModelID)
update.SetValidatedAssetVersion(ValidatedModelVersion)
// DO NOT reset completed when validated model is updated
// update.Add("completed", false)
allowed_statuses := []model.SubmissionStatus{model.SubmissionStatusValidating}
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
err := svc.inner.UpdateSubmissionIfStatus(ctx, params.SubmissionID, allowed_statuses, update)
if err != nil {
return nil, err
return err
}
event_data := model.AuditEventDataChangeValidatedModel{
ValidatedModelID: params.ValidatedModelID,
ValidatedModelVersion: params.ValidatedModelVersion,
ValidatedModelID: ValidatedModelID,
ValidatedModelVersion: ValidatedModelVersion,
}
err = svc.inner.CreateAuditEventChangeValidatedModel(
return svc.inner.CreateAuditEventChangeValidatedModel(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: SubmissionID,
ID: params.SubmissionID,
Type: model.ResourceSubmission,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionSubmissionSubmitted invokes actionSubmissionSubmitted operation.
@@ -86,8 +70,7 @@ func (svc *Submissions) SetValidatedModel(ctx context.Context, params *validator
// Role Validator changes status from Submitting -> Submitted.
//
// POST /submissions/{SubmissionID}/status/validator-submitted
func (svc *Submissions) SetStatusSubmitted(ctx context.Context, params *validator.SubmittedRequest) (*validator.NullResponse, error) {
SubmissionID := int64(params.ID)
func (svc *Service) ActionSubmissionSubmitted(ctx context.Context, params internal.ActionSubmissionSubmittedParams) error {
// transaction
target_status := model.SubmissionStatusSubmitted
update := service.NewSubmissionUpdate()
@@ -97,29 +80,24 @@ func (svc *Submissions) SetStatusSubmitted(ctx context.Context, params *validato
update.SetCreator(params.Creator)
update.SetGameID(uint32(params.GameID))
allowed_statuses := []model.SubmissionStatus{model.SubmissionStatusSubmitting}
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
err := svc.inner.UpdateSubmissionIfStatus(ctx, params.SubmissionID, allowed_statuses, update)
if err != nil {
return nil, err
return err
}
event_data := model.AuditEventDataAction{
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: SubmissionID,
ID: params.SubmissionID,
Type: model.ResourceSubmission,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionSubmissionRequestChanges implements actionSubmissionRequestChanges operation.
@@ -127,16 +105,15 @@ func (svc *Submissions) SetStatusSubmitted(ctx context.Context, params *validato
// (Internal endpoint) Role Validator changes status from Submitting -> RequestChanges.
//
// POST /submissions/{SubmissionID}/status/validator-request-changes
func (svc *Submissions) SetStatusRequestChanges(ctx context.Context, params *validator.SubmissionID) (*validator.NullResponse, error) {
SubmissionID := int64(params.ID)
func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params internal.ActionSubmissionRequestChangesParams) error {
// transaction
target_status := model.SubmissionStatusChangesRequested
update := service.NewSubmissionUpdate()
update.SetStatusID(target_status)
allowed_statuses :=[]model.SubmissionStatus{model.SubmissionStatusSubmitting}
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
err := svc.inner.UpdateSubmissionIfStatus(ctx, params.SubmissionID, allowed_statuses, update)
if err != nil {
return nil, err
return err
}
// push an action audit event
@@ -144,20 +121,15 @@ func (svc *Submissions) SetStatusRequestChanges(ctx context.Context, params *val
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: SubmissionID,
ID: params.SubmissionID,
Type: model.ResourceSubmission,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
@@ -165,36 +137,30 @@ func (svc *Submissions) SetStatusRequestChanges(ctx context.Context, params *val
// Role Validator changes status from Validating -> Validated.
//
// POST /submissions/{SubmissionID}/status/validator-validated
func (svc *Submissions) SetStatusValidated(ctx context.Context, params *validator.SubmissionID) (*validator.NullResponse, error) {
SubmissionID := int64(params.ID)
func (svc *Service) ActionSubmissionValidated(ctx context.Context, params internal.ActionSubmissionValidatedParams) error {
// transaction
target_status := model.SubmissionStatusValidated
update := service.NewSubmissionUpdate()
update.SetStatusID(target_status)
allowed_statuses :=[]model.SubmissionStatus{model.SubmissionStatusValidating}
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
err := svc.inner.UpdateSubmissionIfStatus(ctx, params.SubmissionID, allowed_statuses, update)
if err != nil {
return nil, err
return err
}
event_data := model.AuditEventDataAction{
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: SubmissionID,
ID: params.SubmissionID,
Type: model.ResourceSubmission,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
@@ -202,16 +168,15 @@ func (svc *Submissions) SetStatusValidated(ctx context.Context, params *validato
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
//
// POST /submissions/{SubmissionID}/status/validator-failed
func (svc *Submissions) SetStatusFailed(ctx context.Context, params *validator.SubmissionID) (*validator.NullResponse, error) {
SubmissionID := int64(params.ID)
func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params internal.ActionSubmissionAcceptedParams) error {
// transaction
target_status := model.SubmissionStatusAcceptedUnvalidated
update := service.NewSubmissionUpdate()
update.SetStatusID(target_status)
allowed_statuses :=[]model.SubmissionStatus{model.SubmissionStatusValidating}
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
err := svc.inner.UpdateSubmissionIfStatus(ctx, params.SubmissionID, allowed_statuses, update)
if err != nil {
return nil, err
return err
}
// push an action audit event
@@ -219,20 +184,15 @@ func (svc *Submissions) SetStatusFailed(ctx context.Context, params *validator.S
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: SubmissionID,
ID: params.SubmissionID,
Type: model.ResourceSubmission,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
@@ -240,37 +200,31 @@ func (svc *Submissions) SetStatusFailed(ctx context.Context, params *validator.S
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
//
// POST /submissions/{SubmissionID}/status/validator-uploaded
func (svc *Submissions) SetStatusUploaded(ctx context.Context, params *validator.StatusUploadedRequest) (*validator.NullResponse, error) {
SubmissionID := int64(params.ID)
func (svc *Service) ActionSubmissionUploaded(ctx context.Context, params internal.ActionSubmissionUploadedParams) error {
// transaction
target_status := model.SubmissionStatusUploaded
update := service.NewSubmissionUpdate()
update.SetStatusID(target_status)
update.SetUploadedAssetID(params.UploadedAssetID)
update.SetUploadedAssetID(uint64(params.UploadedAssetID))
allowed_statuses :=[]model.SubmissionStatus{model.SubmissionStatusUploading}
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
err := svc.inner.UpdateSubmissionIfStatus(ctx, params.SubmissionID, allowed_statuses, update)
if err != nil {
return nil, err
return err
}
event_data := model.AuditEventDataAction{
TargetStatus: uint32(target_status),
}
err = svc.inner.CreateAuditEventAction(
return svc.inner.CreateAuditEventAction(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: SubmissionID,
ID: params.SubmissionID,
Type: model.ResourceSubmission,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// CreateSubmissionAuditError implements createSubmissionAuditError operation.
@@ -278,26 +232,20 @@ func (svc *Submissions) SetStatusUploaded(ctx context.Context, params *validator
// Post an error to the audit log
//
// POST /submissions/{SubmissionID}/error
func (svc *Submissions) CreateAuditError(ctx context.Context, params *validator.AuditErrorRequest) (*validator.NullResponse, error) {
SubmissionID := int64(params.ID)
func (svc *Service) CreateSubmissionAuditError(ctx context.Context, params internal.CreateSubmissionAuditErrorParams) (error) {
event_data := model.AuditEventDataError{
Error: params.ErrorMessage,
}
err := svc.inner.CreateAuditEventError(
return svc.inner.CreateAuditEventError(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: SubmissionID,
ID: params.SubmissionID,
Type: model.ResourceSubmission,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// CreateSubmissionAuditCheckList implements createSubmissionAuditCheckList operation.
@@ -305,11 +253,10 @@ func (svc *Submissions) CreateAuditError(ctx context.Context, params *validator.
// Post a checklist to the audit log
//
// POST /submissions/{SubmissionID}/checklist
func (svc *Submissions) CreateAuditChecklist(ctx context.Context, params *validator.AuditChecklistRequest) (*validator.NullResponse, error) {
SubmissionID := int64(params.ID)
check_list := make([]model.Check, len(params.CheckList))
for i, check := range params.CheckList {
check_list[i] = model.Check{
func (svc *Service) CreateSubmissionAuditCheckList(ctx context.Context, check_list internal.CheckList, params internal.CreateSubmissionAuditCheckListParams) (error) {
check_list2 := make([]model.Check, len(check_list))
for i, check := range check_list {
check_list2[i] = model.Check{
Name: check.Name,
Summary: check.Summary,
Passed: check.Passed,
@@ -317,36 +264,41 @@ func (svc *Submissions) CreateAuditChecklist(ctx context.Context, params *valida
}
event_data := model.AuditEventDataCheckList{
CheckList: check_list,
CheckList: check_list2,
}
err := svc.inner.CreateAuditEventCheckList(
return svc.inner.CreateAuditEventCheckList(
ctx,
model.ValidatorUserID,
ValidtorUserID,
model.Resource{
ID: SubmissionID,
ID: params.SubmissionID,
Type: model.ResourceSubmission,
},
event_data,
)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}
// POST /submissions
func (svc *Submissions) Create(ctx context.Context, request *validator.SubmissionCreate) (*validator.SubmissionID, error) {
func (svc *Service) CreateSubmission(ctx context.Context, request *internal.SubmissionCreate) (*internal.SubmissionID, error) {
// sanitization
if request.GameID<0||
request.AssetOwner<0||
request.AssetID<0||
request.AssetVersion<0{
return nil, ErrNegativeID
}
var GameID=uint32(request.GameID);
var Submitter=uint64(request.AssetOwner);
var AssetID=uint64(request.AssetID);
var AssetVersion=uint64(request.AssetVersion);
var Status=model.SubmissionStatus(request.Status);
var roles=model.Roles(request.Roles);
// Check if an active submission with the same asset id exists
{
filter := service.NewSubmissionFilter()
filter.SetAssetID(request.AssetID)
filter.SetAssetVersion(request.AssetVersion)
filter.SetAssetID(AssetID)
filter.SetAssetVersion(AssetVersion)
filter.SetStatuses(ActiveSubmissionStatuses)
active_submissions, err := svc.inner.ListSubmissions(ctx, filter, model.Page{
Number: 1,
@@ -360,8 +312,7 @@ func (svc *Submissions) Create(ctx context.Context, request *validator.Submissio
}
}
operation_id := int32(request.OperationID)
operation, err := svc.inner.GetOperation(ctx, operation_id)
operation, err := svc.inner.GetOperation(ctx, request.OperationID)
if err != nil {
return nil, err
}
@@ -379,10 +330,10 @@ func (svc *Submissions) Create(ctx context.Context, request *validator.Submissio
ID: 0,
DisplayName: request.DisplayName,
Creator: request.Creator,
GameID: request.GameID,
GameID: GameID,
Submitter: Submitter,
AssetID: request.AssetID,
AssetVersion: request.AssetVersion,
AssetID: AssetID,
AssetVersion: AssetVersion,
Completed: false,
StatusID: Status,
})
@@ -392,12 +343,12 @@ func (svc *Submissions) Create(ctx context.Context, request *validator.Submissio
// mark the operation as completed and provide the path
params := service.NewOperationCompleteParams(fmt.Sprintf("/submissions/%d", submission.ID))
err = svc.inner.CompleteOperation(ctx, operation_id, params)
err = svc.inner.CompleteOperation(ctx, request.OperationID, params)
if err != nil {
return nil, err
}
return &validator.SubmissionID{
ID: uint64(submission.ID),
return &internal.SubmissionID{
SubmissionID: submission.ID,
}, nil
}

View File

@@ -1,37 +0,0 @@
package validator_controller
import (
"context"
"git.itzana.me/strafesnet/go-grpc/validator"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
type Operations struct {
*validator.UnimplementedValidatorOperationServiceServer
inner *service.Service
}
func NewOperationsController(
inner *service.Service,
) Operations {
return Operations{
inner: inner,
}
}
// ActionOperationFailed implements actionOperationFailed operation.
//
// Fail the specified OperationID with a StatusMessage.
//
// POST /operations/{OperationID}/status/operation-failed
func (svc *Operations) Fail(ctx context.Context, params *validator.OperationFailRequest) (*validator.NullResponse, error) {
fail_params := service.NewOperationFailParams(
params.StatusMessage,
)
err := svc.inner.FailOperation(ctx, int32(params.OperationID), fail_params)
if err != nil {
return nil, err
}
return &validator.NullResponse{}, nil
}

View File

@@ -1,89 +0,0 @@
package validator_controller
import (
"context"
"git.itzana.me/strafesnet/go-grpc/validator"
"git.itzana.me/strafesnet/maps-service/pkg/model"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
type ScriptPolicy struct {
*validator.UnimplementedValidatorScriptPolicyServiceServer
inner *service.Service
}
func NewScriptPolicyController(
inner *service.Service,
) ScriptPolicy {
return ScriptPolicy{
inner: inner,
}
}
// CreateScriptPolicy implements createScriptPolicy operation.
//
// Create a new script policy.
//
// POST /script-policy
func (svc *ScriptPolicy) Create(ctx context.Context, req *validator.ScriptPolicyCreate) (*validator.ScriptPolicyID, error) {
from_script, err := svc.inner.GetScript(ctx, int64(req.FromScriptID))
if err != nil {
return nil, err
}
// the existence of ToScriptID does not need to be validated because it's checked by a foreign key constraint.
script, err := svc.inner.CreateScriptPolicy(ctx, model.ScriptPolicy{
ID: 0,
FromScriptHash: from_script.Hash,
ToScriptID: int64(req.ToScriptID),
Policy: model.Policy(req.Policy),
})
if err != nil {
return nil, err
}
return &validator.ScriptPolicyID{
ID: uint64(script.ID),
}, nil
}
// ListScriptPolicy implements listScriptPolicy operation.
//
// Get list of script policies.
//
// GET /script-policy
func (svc *ScriptPolicy) List(ctx context.Context, params *validator.ScriptPolicyListRequest) (*validator.ScriptPolicyListResponse, error) {
filter := service.NewScriptPolicyFilter()
if params.Filter.FromScriptHash != nil {
filter.SetFromScriptHash(int64(*params.Filter.FromScriptHash))
}
if params.Filter.ToScriptID != nil {
filter.SetToScriptID(int64(*params.Filter.ToScriptID))
}
if params.Filter.Policy != nil {
filter.SetPolicy(int32(*params.Filter.Policy))
}
items, err := svc.inner.ListScriptPolicies(ctx, filter, model.Page{
Number: int32(params.Page.Number),
Size: int32(params.Page.Size),
})
if err != nil {
return nil, err
}
resp := validator.ScriptPolicyListResponse{}
resp.ScriptPolicies = make([]*validator.ScriptPolicy, len(items))
for i, item := range items {
resp.ScriptPolicies[i] = &validator.ScriptPolicy{
ID: uint64(item.ID),
FromScriptHash: uint64(item.FromScriptHash),
ToScriptID: uint64(item.ToScriptID),
Policy: validator.Policy(int32(item.Policy)),
}
}
return &resp, nil
}

View File

@@ -1,119 +0,0 @@
package validator_controller
import (
"context"
"git.itzana.me/strafesnet/go-grpc/validator"
"git.itzana.me/strafesnet/maps-service/pkg/model"
"git.itzana.me/strafesnet/maps-service/pkg/service"
)
type Scripts struct {
*validator.UnimplementedValidatorScriptServiceServer
inner *service.Service
}
func NewScriptsController(
inner *service.Service,
) Scripts {
return Scripts{
inner: inner,
}
}
// CreateScript implements createScript operation.
//
// Create a new script.
//
// POST /scripts
func (svc *Scripts) Create(ctx context.Context, req *validator.ScriptCreate) (*validator.ScriptID, error) {
ResourceID := int64(0)
if req.ResourceID != nil {
ResourceID = int64(*req.ResourceID)
}
script, err := svc.inner.CreateScript(ctx, model.Script{
ID: 0,
Name: req.Name,
Hash: int64(model.HashSource(req.Source)),
Source: req.Source,
ResourceType: model.ResourceType(req.ResourceType),
ResourceID: ResourceID,
})
if err != nil {
return nil, err
}
return &validator.ScriptID{
ID: uint64(script.ID),
}, nil
}
// ListScripts implements listScripts operation.
//
// Get list of scripts.
//
// GET /scripts
func (svc *Scripts) List(ctx context.Context, params *validator.ScriptListRequest) (*validator.ScriptListResponse, error) {
filter := service.NewScriptFilter()
if params.Filter.Hash != nil {
filter.SetHash(int64(*params.Filter.Hash))
}
if params.Filter.Name != nil {
filter.SetName(*params.Filter.Name)
}
if params.Filter.Source != nil {
filter.SetSource(*params.Filter.Source)
}
if params.Filter.ResourceType != nil {
filter.SetResourceType(int32(*params.Filter.ResourceType))
}
if params.Filter.ResourceID != nil {
filter.SetResourceID(int64(*params.Filter.ResourceID))
}
items, err := svc.inner.ListScripts(ctx, filter, model.Page{
Number: int32(params.Page.Number),
Size: int32(params.Page.Size),
})
if err != nil {
return nil, err
}
resp := validator.ScriptListResponse{}
resp.Scripts = make([]*validator.Script, len(items))
for i, item := range items {
resource_id := uint64(item.ResourceID)
resp.Scripts[i] = &validator.Script{
ID: uint64(item.ID),
Name: item.Name,
Hash: uint64(item.Hash),
Source: item.Source,
ResourceType: validator.ResourceType(item.ResourceType),
ResourceID: &resource_id,
}
}
return &resp, nil
}
// GetScript implements getScript operation.
//
// Get the specified script by ID.
//
// GET /scripts/{ScriptID}
func (svc *Scripts) Get(ctx context.Context, params *validator.ScriptID) (*validator.Script, error) {
ScriptID := int64(params.ID)
script, err := svc.inner.GetScript(ctx, ScriptID)
if err != nil {
return nil, err
}
ResourceID := uint64(script.ResourceID)
return &validator.Script{
ID: uint64(script.ID),
Name: script.Name,
Hash: uint64(script.Hash),
Source: script.Source,
ResourceType: validator.ResourceType(script.ResourceType),
ResourceID: &ResourceID,
}, nil
}

View File

@@ -1,9 +1,10 @@
[package]
name = "maps-validation"
version = "0.1.1"
edition = "2024"
edition = "2021"
[dependencies]
submissions-api = { path = "api", features = ["internal"], default-features = false, registry = "strafesnet" }
async-nats = "0.42.0"
futures = "0.3.31"
rbx_asset = { version = "0.4.7", registry = "strafesnet" }
@@ -17,5 +18,3 @@ siphasher = "1.0.1"
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread", "signal"] }
heck = "0.5.0"
lazy-regex = "3.4.1"
rust-grpc = { version = "1.2.1", registry = "strafesnet" }
tonic = "0.13.1"

View File

@@ -1,7 +1,7 @@
[package]
name = "submissions-api"
version = "0.8.2"
edition = "2024"
edition = "2021"
publish = ["strafesnet"]
repository = "https://git.itzana.me/StrafesNET/maps-service"
license = "MIT OR Apache-2.0"
@@ -17,3 +17,8 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_repr = "0.1.19"
url = "2"
[features]
default = ["external"]
internal = []
external = []

View File

@@ -33,6 +33,11 @@ impl Context{
self.client.get(url)
.send().await
}
#[cfg(feature="internal")]
pub async fn post_empty_body(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{
self.client.post(url)
.send().await
}
pub async fn post(&self,url:impl reqwest::IntoUrl,body:impl Into<reqwest::Body>)->Result<reqwest::Response,reqwest::Error>{
self.client.post(url)
.header("Content-Type","application/json")

View File

@@ -0,0 +1,241 @@
use crate::types::*;
#[derive(Clone)]
pub struct Context(crate::context::Context);
// conditionally include specified query pairs
macro_rules! query_pairs{
($url:expr,)=>{
$url
};
($url:expr,$(($param:expr,$value:expr))+)=>{
{
let mut url=$url;
url.query_pairs_mut()
$(.append_pair($param,$value))*;
url
}
};
}
// there are lots of action endpoints and they all follow the same pattern
macro_rules! action{
($system:expr,$fname:ident,$config:ident,$config_type:ident,$action:expr,$config_submission_id:expr,$(($param:expr,$value:expr))*)=>{
pub async fn $fname(&self,$config:$config_type)->Result<(),Error>{
let url_raw=format!(concat!("{}/",$system,"/{}/",$action),self.0.base_url,$config_submission_id);
let url=query_pairs!(reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?,$(($param,$value))*);
response_ok(
self.0.post_empty_body(url).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?;
Ok(())
}
};
}
impl Context{
pub fn new(base_url:String)->reqwest::Result<Self>{
Ok(Self(crate::context::Context::new(base_url,None)?))
}
pub async fn get_script(&self,config:GetScriptRequest)->Result<ScriptResponse,Error>{
let url_raw=format!("{}/scripts/{}",self.0.base_url,config.ScriptID.0);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
response_ok(
self.0.get(url).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
pub async fn get_scripts(&self,config:GetScriptsRequest<'_>)->Result<Vec<ScriptResponse>,Error>{
let url_raw=format!("{}/scripts",self.0.base_url);
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
{
let mut query_pairs=url.query_pairs_mut();
query_pairs.append_pair("Page",config.Page.to_string().as_str());
query_pairs.append_pair("Limit",config.Limit.to_string().as_str());
if let Some(name)=config.Name{
query_pairs.append_pair("Name",name);
}
if let Some(hash)=config.Hash{
query_pairs.append_pair("Hash",hash);
}
if let Some(source)=config.Source{
query_pairs.append_pair("Source",source);
}
if let Some(resource_type)=config.ResourceType{
query_pairs.append_pair("ResourceType",(resource_type as i32).to_string().as_str());
}
if let Some(ResourceID(resource_id))=config.ResourceID{
query_pairs.append_pair("ResourceID",resource_id.to_string().as_str());
}
}
response_ok(
self.0.get(url).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
pub async fn get_script_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptResponse>,ScriptSingleItemError>{
let scripts=self.get_scripts(GetScriptsRequest{
Page:1,
Limit:2,
Hash:Some(config.hash),
Name:None,
Source:None,
ResourceType:None,
ResourceID:None,
}).await.map_err(SingleItemError::Other)?;
if 1<scripts.len(){
return Err(SingleItemError::DuplicateItems(scripts.into_iter().map(|item|item.ID).collect()));
}
Ok(scripts.into_iter().next())
}
pub async fn create_script(&self,config:CreateScriptRequest<'_>)->Result<ScriptIDResponse,Error>{
let url_raw=format!("{}/scripts",self.0.base_url);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
let body=serde_json::to_string(&config).map_err(Error::JSON)?;
response_ok(
self.0.post(url,body).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
pub async fn get_script_policies(&self,config:GetScriptPoliciesRequest<'_>)->Result<Vec<ScriptPolicyResponse>,Error>{
let url_raw=format!("{}/script-policy",self.0.base_url);
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
{
let mut query_pairs=url.query_pairs_mut();
query_pairs.append_pair("Page",config.Page.to_string().as_str());
query_pairs.append_pair("Limit",config.Limit.to_string().as_str());
if let Some(hash)=config.FromScriptHash{
query_pairs.append_pair("FromScriptHash",hash);
}
if let Some(script_id)=config.ToScriptID{
query_pairs.append_pair("ToScriptID",script_id.0.to_string().as_str());
}
if let Some(policy)=config.Policy{
query_pairs.append_pair("Policy",(policy as i32).to_string().as_str());
}
}
response_ok(
self.0.get(url).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
pub async fn get_script_policy_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptPolicyResponse>,ScriptPolicySingleItemError>{
let policies=self.get_script_policies(GetScriptPoliciesRequest{
Page:1,
Limit:2,
FromScriptHash:Some(config.hash),
ToScriptID:None,
Policy:None,
}).await.map_err(SingleItemError::Other)?;
if 1<policies.len(){
return Err(SingleItemError::DuplicateItems(policies.into_iter().map(|item|item.ID).collect()));
}
Ok(policies.into_iter().next())
}
pub async fn create_script_policy(&self,config:CreateScriptPolicyRequest)->Result<ScriptPolicyIDResponse,Error>{
let url_raw=format!("{}/script-policy",self.0.base_url);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
let body=serde_json::to_string(&config).map_err(Error::JSON)?;
response_ok(
self.0.post(url,body).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
pub async fn create_submission(&self,config:CreateSubmissionRequest<'_>)->Result<SubmissionIDResponse,Error>{
let url_raw=format!("{}/submissions",self.0.base_url);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
let body=serde_json::to_string(&config).map_err(Error::JSON)?;
response_ok(
self.0.post(url,body).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
pub async fn create_submission_audit_check_list(&self,config:CreateSubmissionAuditCheckListRequest<'_>)->Result<(),Error>{
let url_raw=format!("{}/submissions/{}/checklist",self.0.base_url,config.SubmissionID.0);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
let body=serde_json::to_string(&config.CheckList).map_err(Error::JSON)?;
response_ok(
self.0.post(url,body).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?;
Ok(())
}
// simple submission endpoints
action!("submissions",action_submission_request_changes,config,ActionSubmissionRequestChangesRequest,"status/validator-request-changes",config.SubmissionID.0,);
action!("submissions",action_submission_submitted,config,ActionSubmissionSubmittedRequest,"status/validator-submitted",config.SubmissionID.0,
("ModelVersion",config.ModelVersion.to_string().as_str())
("DisplayName",config.DisplayName.as_str())
("Creator",config.Creator.as_str())
("GameID",(config.GameID as u8).to_string().as_str())
);
action!("submissions",action_submission_validated,config,SubmissionID,"status/validator-validated",config.0,);
action!("submissions",update_submission_validated_model,config,UpdateSubmissionModelRequest,"validated-model",config.SubmissionID.0,
("ValidatedModelID",config.ModelID.to_string().as_str())
("ValidatedModelVersion",config.ModelVersion.to_string().as_str())
);
action!("submissions",action_submission_uploaded,config,ActionSubmissionUploadedRequest,"status/validator-uploaded",config.SubmissionID.0,
("UploadedAssetID",config.UploadedAssetID.to_string().as_str())
);
action!("submissions",action_submission_accepted,config,ActionSubmissionAcceptedRequest,"status/validator-failed",config.SubmissionID.0,);
action!("submissions",create_submission_audit_error,config,CreateSubmissionAuditErrorRequest,"error",config.SubmissionID.0,
("ErrorMessage",config.ErrorMessage.as_str())
);
pub async fn create_mapfix(&self,config:CreateMapfixRequest<'_>)->Result<MapfixIDResponse,Error>{
let url_raw=format!("{}/mapfixes",self.0.base_url);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
let body=serde_json::to_string(&config).map_err(Error::JSON)?;
response_ok(
self.0.post(url,body).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?
.json().await.map_err(Error::ReqwestJson)
}
pub async fn create_mapfix_audit_check_list(&self,config:CreateMapfixAuditCheckListRequest<'_>)->Result<(),Error>{
let url_raw=format!("{}/mapfixes/{}/checklist",self.0.base_url,config.MapfixID.0);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
let body=serde_json::to_string(&config.CheckList).map_err(Error::JSON)?;
response_ok(
self.0.post(url,body).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?;
Ok(())
}
// simple mapfixes endpoints
action!("mapfixes",action_mapfix_request_changes,config,ActionMapfixRequestChangesRequest,"status/validator-request-changes",config.MapfixID.0,);
action!("mapfixes",action_mapfix_submitted,config,ActionMapfixSubmittedRequest,"status/validator-submitted",config.MapfixID.0,
("ModelVersion",config.ModelVersion.to_string().as_str())
("DisplayName",config.DisplayName.as_str())
("Creator",config.Creator.as_str())
("GameID",(config.GameID as u8).to_string().as_str())
);
action!("mapfixes",action_mapfix_validated,config,MapfixID,"status/validator-validated",config.0,);
action!("mapfixes",update_mapfix_validated_model,config,UpdateMapfixModelRequest,"validated-model",config.MapfixID.0,
("ValidatedModelID",config.ModelID.to_string().as_str())
("ValidatedModelVersion",config.ModelVersion.to_string().as_str())
);
action!("mapfixes",action_mapfix_uploaded,config,ActionMapfixUploadedRequest,"status/validator-uploaded",config.MapfixID.0,);
action!("mapfixes",action_mapfix_accepted,config,ActionMapfixAcceptedRequest,"status/validator-failed",config.MapfixID.0,);
// simple operation endpoint
action!("operations",action_operation_failed,config,ActionOperationFailedRequest,"status/operation-failed",config.OperationID.0,
("StatusMessage",config.StatusMessage.as_str())
);
action!("mapfixes",create_mapfix_audit_error,config,CreateMapfixAuditErrorRequest,"error",config.MapfixID.0,
("ErrorMessage",config.ErrorMessage.as_str())
);
}

View File

@@ -2,6 +2,11 @@ mod context;
pub use context::Cookie;
pub mod types;
#[cfg(feature="internal")]
pub mod internal;
#[cfg(feature="external")]
pub mod external;
//lazy reexports

View File

@@ -4,7 +4,7 @@ use crate::rbx_util::{get_mapinfo,get_root_instance,read_dom,ReadDomError,GameID
use heck::{ToSnakeCase,ToTitleCase};
use rbx_dom_weak::Instance;
use rust_grpc::validator::Check;
use submissions_api::types::Check;
#[allow(dead_code)]
#[derive(Debug)]
@@ -640,27 +640,27 @@ impl<D:std::fmt::Display> std::fmt::Display for Duplicates<D>{
macro_rules! passed{
($name:literal)=>{
Check{
name:$name.to_owned(),
summary:String::new(),
passed:true,
Name:$name,
Summary:String::new(),
Passed:true,
}
}
}
macro_rules! summary{
($name:literal,$summary:expr)=>{
Check{
name:$name.to_owned(),
summary:$summary,
passed:false,
Name:$name,
Summary:$summary,
Passed:false,
}
};
}
macro_rules! summary_format{
($name:literal,$fmt:literal)=>{
Check{
name:$name.to_owned(),
summary:format!($fmt),
passed:false,
Name:$name,
Summary:format!($fmt),
Passed:false,
}
};
}
@@ -813,7 +813,7 @@ impl MapCheck<'_>{
summary_format!("UnanchoredParts","{count} unanchored {plural}: {context}")
}
};
Ok(MapCheckList{checks:vec![
Ok(MapCheckList{checks:Box::new([
model_class,
model_name,
display_name,
@@ -831,13 +831,13 @@ impl MapCheck<'_>{
missing_wormhole_in,
duplicate_wormhole_out,
unanchored_parts,
]})
])})
}
}
#[derive(serde::Serialize)]
pub struct MapCheckList{
pub checks:Vec<Check>,
pub checks:Box<[Check;17]>,
}
pub struct CheckListAndVersion{

View File

@@ -5,7 +5,7 @@ use crate::nats_types::CheckMapfixRequest;
#[derive(Debug)]
pub enum Error{
Check(crate::check::Error),
ApiActionMapfixCheck(tonic::Status),
ApiActionMapfixCheck(submissions_api::Error),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -22,13 +22,13 @@ impl crate::message_handler::MessageHandler{
// update the mapfix depending on the result
match check_result{
Ok(CheckListAndVersion{status:Ok(map_info),version})=>{
self.mapfixes.set_status_submitted(
rust_grpc::validator::SubmittedRequest{
id:mapfix_id,
model_version:version,
display_name:map_info.display_name,
creator:map_info.creator,
game_id:map_info.game_id as u32,
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.into(),
}
).await.map_err(Error::ApiActionMapfixCheck)?;
@@ -36,31 +36,29 @@ impl crate::message_handler::MessageHandler{
return Ok(());
},
// update the mapfix model status to request changes
Ok(CheckListAndVersion{status:Err(check_list),..})=>{
self.mapfixes.create_audit_checklist(
rust_grpc::validator::AuditChecklistRequest{
id:mapfix_id,
check_list:check_list.checks,
}
).await.map_err(Error::ApiActionMapfixCheck)?;
},
Ok(CheckListAndVersion{status:Err(check_list),..})=>self.api.create_mapfix_audit_check_list(
submissions_api::types::CreateMapfixAuditCheckListRequest{
MapfixID:mapfix_id,
CheckList:check_list.checks.as_slice(),
}
).await.map_err(Error::ApiActionMapfixCheck)?,
// update the mapfix model status to request changes
Err(e)=>{
// log error
println!("[check_mapfix] Error: {e}");
self.mapfixes.create_audit_error(
rust_grpc::validator::AuditErrorRequest{
id:mapfix_id,
error_message:e.to_string(),
self.api.create_mapfix_audit_error(
submissions_api::types::CreateMapfixAuditErrorRequest{
MapfixID:mapfix_id,
ErrorMessage:e.to_string(),
}
).await.map_err(Error::ApiActionMapfixCheck)?;
},
}
self.mapfixes.set_status_request_changes(
rust_grpc::validator::MapfixId{
id:mapfix_id,
self.api.action_mapfix_request_changes(
submissions_api::types::ActionMapfixRequestChangesRequest{
MapfixID:mapfix_id,
}
).await.map_err(Error::ApiActionMapfixCheck)?;

View File

@@ -5,7 +5,7 @@ use crate::nats_types::CheckSubmissionRequest;
#[derive(Debug)]
pub enum Error{
Check(crate::check::Error),
ApiActionSubmissionCheck(tonic::Status),
ApiActionSubmissionCheck(submissions_api::Error),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -23,13 +23,13 @@ impl crate::message_handler::MessageHandler{
match check_result{
// update the submission model status to submitted
Ok(CheckListAndVersion{status:Ok(map_info),version})=>{
self.submissions.set_status_submitted(
rust_grpc::validator::SubmittedRequest{
id:submission_id,
model_version:version,
display_name:map_info.display_name,
creator:map_info.creator,
game_id:map_info.game_id as u32,
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.into(),
}
).await.map_err(Error::ApiActionSubmissionCheck)?;
@@ -37,31 +37,29 @@ impl crate::message_handler::MessageHandler{
return Ok(());
},
// update the submission model status to request changes
Ok(CheckListAndVersion{status:Err(check_list),..})=>{
self.submissions.create_audit_checklist(
rust_grpc::validator::AuditChecklistRequest{
id:submission_id,
check_list:check_list.checks,
Ok(CheckListAndVersion{status:Err(check_list),..})=>self.api.create_submission_audit_check_list(
submissions_api::types::CreateSubmissionAuditCheckListRequest{
SubmissionID:submission_id,
CheckList:check_list.checks.as_slice(),
}
).await.map_err(Error::ApiActionSubmissionCheck)?;
},
).await.map_err(Error::ApiActionSubmissionCheck)?,
// update the submission model status to request changes
Err(e)=>{
// log error
println!("[check_submission] Error: {e}");
self.submissions.create_audit_error(
rust_grpc::validator::AuditErrorRequest{
id:submission_id,
error_message:e.to_string(),
self.api.create_submission_audit_error(
submissions_api::types::CreateSubmissionAuditErrorRequest{
SubmissionID:submission_id,
ErrorMessage:e.to_string(),
}
).await.map_err(Error::ApiActionSubmissionCheck)?;
},
}
self.submissions.set_status_request_changes(
rust_grpc::validator::SubmissionId{
id:submission_id,
self.api.action_submission_request_changes(
submissions_api::types::ActionSubmissionRequestChangesRequest{
SubmissionID:submission_id,
}
).await.map_err(Error::ApiActionSubmissionCheck)?;

View File

@@ -5,7 +5,7 @@ use crate::create::CreateRequest;
#[derive(Debug)]
pub enum Error{
Create(crate::create::Error),
ApiActionMapfixCreate(tonic::Status),
ApiActionMapfixCreate(submissions_api::Error),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -22,22 +22,22 @@ impl crate::message_handler::MessageHandler{
}).await.map_err(Error::Create)?;
// call create on api
self.mapfixes.create(rust_grpc::validator::MapfixCreate{
operation_id:create_info.OperationID,
asset_owner:create_request.AssetOwner,
display_name:create_request.DisplayName.unwrap_or_default(),
creator:create_request.Creator.unwrap_or_default(),
self.api.create_mapfix(submissions_api::types::CreateMapfixRequest{
OperationID:create_info.OperationID,
AssetOwner:create_request.AssetOwner as i64,
DisplayName:create_request.DisplayName.as_deref().unwrap_or_default(),
Creator:create_request.Creator.as_deref().unwrap_or_default(),
// not great TODO: make this great
game_id:create_request.GameID.unwrap_or(crate::rbx_util::GameID::Bhop) as u32,
asset_id:create_info.ModelID,
asset_version:create_request.AssetVersion,
target_asset_id:create_info.TargetAssetID,
description:create_info.Description,
GameID:create_request.GameID.unwrap_or(crate::rbx_util::GameID::Bhop).into(),
AssetID:create_info.ModelID,
AssetVersion:create_request.AssetVersion,
TargetAssetID:create_info.TargetAssetID,
Description:create_info.Description.as_str(),
}).await.map_err(Error::ApiActionMapfixCreate)?;
Ok(())
}
pub async fn create_mapfix(&self,create_info:CreateMapfixRequest)->Result<(),tonic::Status>{
pub async fn create_mapfix(&self,create_info:CreateMapfixRequest)->Result<(),submissions_api::Error>{
let operation_id=create_info.OperationID;
let create_result=self.create_mapfix_inner(create_info).await;
@@ -46,9 +46,9 @@ impl crate::message_handler::MessageHandler{
// log error
println!("[create_mapfix] Error: {e}");
self.operations.fail(rust_grpc::validator::OperationFailRequest{
operation_id,
status_message:e.to_string(),
self.api.action_operation_failed(submissions_api::types::ActionOperationFailedRequest{
OperationID:operation_id,
StatusMessage:e.to_string(),
}).await?;
}

View File

@@ -6,7 +6,7 @@ use crate::rbx_util::GameID;
#[derive(Debug)]
pub enum Error{
Create(crate::create::Error),
ApiActionSubmissionCreate(tonic::Status),
ApiActionSubmissionCreate(submissions_api::Error),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -23,35 +23,35 @@ impl crate::message_handler::MessageHandler{
// grab values from submission form, otherwise try to fill blanks from map data
let display_name=if create_info.DisplayName.is_empty(){
create_request.DisplayName.unwrap_or_default()
create_request.DisplayName.as_deref().unwrap_or_default()
}else{
create_info.DisplayName
create_info.DisplayName.as_str()
};
let creator=if create_info.Creator.is_empty(){
create_request.Creator.unwrap_or_default()
create_request.Creator.as_deref().unwrap_or_default()
}else{
create_info.Creator
create_info.Creator.as_str()
};
let game_id=create_info.GameID.try_into().ok().or(create_request.GameID).unwrap_or(GameID::Bhop);
// call create on api
self.submissions.create(rust_grpc::validator::SubmissionCreate{
operation_id:create_info.OperationID,
asset_owner:create_request.AssetOwner,
display_name:display_name,
creator:creator,
game_id:game_id as u32,
asset_id:create_info.ModelID,
asset_version:create_request.AssetVersion,
status:create_info.Status,
roles:create_info.Roles,
self.api.create_submission(submissions_api::types::CreateSubmissionRequest{
OperationID:create_info.OperationID,
AssetOwner:create_request.AssetOwner as i64,
DisplayName:display_name,
Creator:creator,
GameID:game_id.into(),
AssetID:create_info.ModelID,
AssetVersion:create_request.AssetVersion,
Status:create_info.Status,
Roles:create_info.Roles,
}).await.map_err(Error::ApiActionSubmissionCreate)?;
Ok(())
}
pub async fn create_submission(&self,create_info:CreateSubmissionRequest)->Result<(),tonic::Status>{
pub async fn create_submission(&self,create_info:CreateSubmissionRequest)->Result<(),submissions_api::Error>{
let operation_id=create_info.OperationID;
let create_result=self.create_submission_inner(create_info).await;
@@ -60,9 +60,9 @@ impl crate::message_handler::MessageHandler{
// log error
println!("[create_submission] Error: {e}");
self.operations.fail(rust_grpc::validator::OperationFailRequest{
operation_id:operation_id,
status_message:e.to_string(),
self.api.action_operation_failed(submissions_api::types::ActionOperationFailedRequest{
OperationID:operation_id,
StatusMessage:e.to_string(),
}).await?;
}

View File

@@ -1,19 +0,0 @@
use rust_grpc::validator::{ScriptId,ScriptPolicyId};
#[derive(Debug)]
#[expect(dead_code)]
pub enum SingleItemError<Items>{
DuplicateItems(Items),
Other(tonic::Status),
}
impl<Items> std::fmt::Display for SingleItemError<Items>
where
Items:std::fmt::Debug
{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl<Items> std::error::Error for SingleItemError<Items> where Items:std::fmt::Debug{}
pub type ScriptSingleItemError=SingleItemError<Vec<ScriptId>>;
pub type ScriptPolicySingleItemError=SingleItemError<Vec<ScriptPolicyId>>;

View File

@@ -1,23 +0,0 @@
use crate::endpoint;
use rust_grpc::validator::*;
pub type ValidatorMapfixesServiceClient=rust_grpc::validator::validator_mapfix_service_client::ValidatorMapfixServiceClient<tonic::transport::channel::Channel>;
#[derive(Clone)]
pub struct Service{
client:ValidatorMapfixesServiceClient,
}
impl Service{
pub fn new(
client:ValidatorMapfixesServiceClient,
)->Self{
Self{client}
}
endpoint!(create,MapfixCreate,MapfixId);
endpoint!(create_audit_error,AuditErrorRequest,NullResponse);
endpoint!(create_audit_checklist,AuditChecklistRequest,NullResponse);
endpoint!(set_validated_model,ValidatedModelRequest,NullResponse);
endpoint!(set_status_submitted,SubmittedRequest,NullResponse);
endpoint!(set_status_request_changes,MapfixId,NullResponse);
endpoint!(set_status_validated,MapfixId,NullResponse);
endpoint!(set_status_failed,MapfixId,NullResponse);
endpoint!(set_status_uploaded,MapfixId,NullResponse);
}

View File

@@ -1,17 +0,0 @@
pub mod error;
pub mod mapfixes;
pub mod operations;
pub mod scripts;
pub mod script_policy;
pub mod submissions;
#[macro_export]
macro_rules! endpoint{
($fn:ident,$in:ident,$out:ident)=>{
pub async fn $fn(&self,request:$in)->Result<$out,tonic::Status>{
Ok(self.client.clone().$fn(request).await?.into_inner())
}
};
}

View File

@@ -1,15 +0,0 @@
use crate::endpoint;
use rust_grpc::validator::*;
pub type ValidatorOperationsServiceClient=rust_grpc::validator::validator_operation_service_client::ValidatorOperationServiceClient<tonic::transport::channel::Channel>;
#[derive(Clone)]
pub struct Service{
client:ValidatorOperationsServiceClient,
}
impl Service{
pub fn new(
client:ValidatorOperationsServiceClient,
)->Self{
Self{client}
}
endpoint!(fail,OperationFailRequest,NullResponse);
}

View File

@@ -1,34 +0,0 @@
use crate::endpoint;
use crate::grpc::error::ScriptPolicySingleItemError;
use rust_grpc::validator::*;
pub type ValidatorScriptPolicyServiceClient=rust_grpc::validator::validator_script_policy_service_client::ValidatorScriptPolicyServiceClient<tonic::transport::channel::Channel>;
#[derive(Clone)]
pub struct Service{
client:ValidatorScriptPolicyServiceClient,
}
impl Service{
pub fn new(
client:ValidatorScriptPolicyServiceClient,
)->Self{
Self{client}
}
endpoint!(create,ScriptPolicyCreate,ScriptPolicyId);
endpoint!(list,ScriptPolicyListRequest,ScriptPolicyListResponse);
pub async fn get_from_hash(&self,hash:u64)->Result<Option<ScriptPolicy>,ScriptPolicySingleItemError>{
let policies=self.list(ScriptPolicyListRequest{
filter:Some(ScriptPolicyFilter{
from_script_hash:Some(hash),
to_script_id:None,
policy:None,
}),
page:Some(Pagination{
number:1,
size:2,
}),
}).await.map_err(ScriptPolicySingleItemError::Other)?;
if 1<policies.script_policies.len(){
return Err(ScriptPolicySingleItemError::DuplicateItems(policies.script_policies.into_iter().map(|item|ScriptPolicyId{id:item.id}).collect()));
}
Ok(policies.script_policies.into_iter().next())
}
}

View File

@@ -1,37 +0,0 @@
use crate::endpoint;
use crate::grpc::error::ScriptSingleItemError;
use rust_grpc::validator::*;
pub type ValidatorScriptsServiceClient=rust_grpc::validator::validator_script_service_client::ValidatorScriptServiceClient<tonic::transport::channel::Channel>;
#[derive(Clone)]
pub struct Service{
client:ValidatorScriptsServiceClient,
}
impl Service{
pub fn new(
client:ValidatorScriptsServiceClient,
)->Self{
Self{client}
}
endpoint!(create,ScriptCreate,ScriptId);
endpoint!(get,ScriptId,Script);
endpoint!(list,ScriptListRequest,ScriptListResponse);
pub async fn get_from_hash(&self,hash:u64)->Result<Option<Script>,ScriptSingleItemError>{
let policies=self.list(ScriptListRequest{
filter:Some(ScriptFilter{
hash:Some(hash),
name:None,
source:None,
resource_type:None,
resource_id:None,
}),
page:Some(Pagination{
number:1,
size:2,
}),
}).await.map_err(ScriptSingleItemError::Other)?;
if 1<policies.scripts.len(){
return Err(ScriptSingleItemError::DuplicateItems(policies.scripts.into_iter().map(|item|ScriptId{id:item.id}).collect()));
}
Ok(policies.scripts.into_iter().next())
}
}

View File

@@ -1,23 +0,0 @@
use crate::endpoint;
use rust_grpc::validator::*;
pub type ValidatorSubmissionsServiceClient=rust_grpc::validator::validator_submission_service_client::ValidatorSubmissionServiceClient<tonic::transport::channel::Channel>;
#[derive(Clone)]
pub struct Service{
client:ValidatorSubmissionsServiceClient,
}
impl Service{
pub fn new(
client:ValidatorSubmissionsServiceClient,
)->Self{
Self{client}
}
endpoint!(create,SubmissionCreate,SubmissionId);
endpoint!(create_audit_error,AuditErrorRequest,NullResponse);
endpoint!(create_audit_checklist,AuditChecklistRequest,NullResponse);
endpoint!(set_validated_model,ValidatedModelRequest,NullResponse);
endpoint!(set_status_submitted,SubmittedRequest,NullResponse);
endpoint!(set_status_request_changes,SubmissionId,NullResponse);
endpoint!(set_status_validated,SubmissionId,NullResponse);
endpoint!(set_status_failed,SubmissionId,NullResponse);
endpoint!(set_status_uploaded,StatusUploadedRequest,NullResponse);
}

View File

@@ -1,12 +1,9 @@
use futures::StreamExt;
mod download;
mod grpc;
mod rbx_util;
mod message_handler;
mod nats_types;
mod types;
mod download;
mod check;
mod check_mapfix;
mod check_submission;
@@ -22,7 +19,7 @@ mod validate_submission;
#[allow(dead_code)]
#[derive(Debug)]
pub enum StartupError{
API(tonic::transport::Error),
API(submissions_api::ReqwestError),
NatsConnect(async_nats::ConnectError),
NatsGetStream(async_nats::jetstream::context::GetStreamError),
NatsConsumer(async_nats::jetstream::stream::ConsumerError),
@@ -57,14 +54,7 @@ async fn main()->Result<(),StartupError>{
// maps-service api
let api_host_internal=std::env::var("API_HOST_INTERNAL").expect("API_HOST_INTERNAL env required");
let (mapfixes,operations,scripts,script_policy,submissions)=tokio::try_join!(
crate::grpc::mapfixes::ValidatorMapfixesServiceClient::connect(api_host_internal.clone()),
crate::grpc::operations::ValidatorOperationsServiceClient::connect(api_host_internal.clone()),
crate::grpc::scripts::ValidatorScriptsServiceClient::connect(api_host_internal.clone()),
crate::grpc::script_policy::ValidatorScriptPolicyServiceClient::connect(api_host_internal.clone()),
crate::grpc::submissions::ValidatorSubmissionsServiceClient::connect(api_host_internal.clone()),
).map_err(StartupError::API)?;
let message_handler=message_handler::MessageHandler::new(cloud_context,cookie_context,group_id,mapfixes,operations,scripts,script_policy,submissions);
let api=submissions_api::internal::Context::new(api_host_internal).map_err(StartupError::API)?;
// nats
let nats_host=std::env::var("NATS_HOST").expect("NATS_HOST env required");
@@ -97,12 +87,14 @@ async fn main()->Result<(),StartupError>{
consumer.messages().await.map_err(StartupError::NatsStream)
};
// run futures
let mut messages=nats_fut.await?;
let message_handler=message_handler::MessageHandler::new(cloud_context,cookie_context,group_id,api);
// Create a signal listener for SIGTERM
let mut sig_term=tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()).expect("Failed to create SIGTERM signal listener");
// run futures
let mut messages=nats_fut.await?;
// process up to PARALLEL_REQUESTS in parallel
let main_loop=async move{
static SEM:tokio::sync::Semaphore=tokio::sync::Semaphore::const_new(PARALLEL_REQUESTS);

View File

@@ -5,8 +5,8 @@ pub enum HandleMessageError{
DoubleAck(async_nats::Error),
Json(serde_json::Error),
UnknownSubject(String),
CreateMapfix(tonic::Status),
CreateSubmission(tonic::Status),
CreateMapfix(submissions_api::Error),
CreateSubmission(submissions_api::Error),
CheckMapfix(crate::check_mapfix::Error),
CheckSubmission(crate::check_submission::Error),
UploadMapfix(crate::upload_mapfix::Error),
@@ -31,11 +31,7 @@ pub struct MessageHandler{
pub(crate) cloud_context:rbx_asset::cloud::Context,
pub(crate) cookie_context:rbx_asset::cookie::Context,
pub(crate) group_id:Option<u64>,
pub(crate) mapfixes:crate::grpc::mapfixes::Service,
pub(crate) operations:crate::grpc::operations::Service,
pub(crate) scripts:crate::grpc::scripts::Service,
pub(crate) script_policy:crate::grpc::script_policy::Service,
pub(crate) submissions:crate::grpc::submissions::Service,
pub(crate) api:submissions_api::internal::Context,
}
impl MessageHandler{
@@ -43,21 +39,13 @@ impl MessageHandler{
cloud_context:rbx_asset::cloud::Context,
cookie_context:rbx_asset::cookie::Context,
group_id:Option<u64>,
mapfixes:crate::grpc::mapfixes::ValidatorMapfixesServiceClient,
operations:crate::grpc::operations::ValidatorOperationsServiceClient,
scripts:crate::grpc::scripts::ValidatorScriptsServiceClient,
script_policy:crate::grpc::script_policy::ValidatorScriptPolicyServiceClient,
submissions:crate::grpc::submissions::ValidatorSubmissionsServiceClient,
api:submissions_api::internal::Context,
)->Self{
Self{
cloud_context,
cookie_context,
group_id,
mapfixes:crate::grpc::mapfixes::Service::new(mapfixes),
operations:crate::grpc::operations::Service::new(operations),
scripts:crate::grpc::scripts::Service::new(scripts),
script_policy:crate::grpc::script_policy::Service::new(script_policy),
submissions:crate::grpc::submissions::Service::new(submissions),
api,
}
}
pub async fn handle_message_result(&self,message_result:MessageResult)->Result<(),HandleMessageError>{

View File

@@ -1,3 +1,5 @@
use submissions_api::types::{SubmissionID,MapfixID,OperationID};
// These represent the information needed in the nats message
// to perform the operation, not necessarily the over-the-wire format
@@ -8,7 +10,7 @@
#[derive(serde::Deserialize)]
pub struct CreateSubmissionRequest{
// operation_id is passed back in the response message
pub OperationID:u32,
pub OperationID:OperationID,
pub ModelID:u64,
pub DisplayName:String,
pub Creator:String,
@@ -21,7 +23,7 @@ pub struct CreateSubmissionRequest{
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct CreateMapfixRequest{
pub OperationID:u32,
pub OperationID:OperationID,
pub ModelID:u64,
pub TargetAssetID:u64,
pub Description:String,
@@ -30,7 +32,7 @@ pub struct CreateMapfixRequest{
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct CheckSubmissionRequest{
pub SubmissionID:u64,
pub SubmissionID:SubmissionID,
pub ModelID:u64,
pub SkipChecks:bool,
}
@@ -38,7 +40,7 @@ pub struct CheckSubmissionRequest{
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct CheckMapfixRequest{
pub MapfixID:u64,
pub MapfixID:MapfixID,
pub ModelID:u64,
pub SkipChecks:bool,
}
@@ -47,7 +49,7 @@ pub struct CheckMapfixRequest{
#[derive(serde::Deserialize)]
pub struct ValidateSubmissionRequest{
// submission_id is passed back in the response message
pub SubmissionID:u64,
pub SubmissionID:SubmissionID,
pub ModelID:u64,
pub ModelVersion:u64,
pub ValidatedModelID:Option<u64>,
@@ -57,7 +59,7 @@ pub struct ValidateSubmissionRequest{
#[derive(serde::Deserialize)]
pub struct ValidateMapfixRequest{
// submission_id is passed back in the response message
pub MapfixID:u64,
pub MapfixID:MapfixID,
pub ModelID:u64,
pub ModelVersion:u64,
pub ValidatedModelID:Option<u64>,
@@ -67,7 +69,7 @@ pub struct ValidateMapfixRequest{
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct UploadSubmissionRequest{
pub SubmissionID:u64,
pub SubmissionID:SubmissionID,
pub ModelID:u64,
pub ModelVersion:u64,
pub ModelName:String,
@@ -76,7 +78,7 @@ pub struct UploadSubmissionRequest{
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct UploadMapfixRequest{
pub MapfixID:u64,
pub MapfixID:MapfixID,
pub ModelID:u64,
pub ModelVersion:u64,
pub TargetAssetID:u64,

View File

@@ -37,7 +37,15 @@ pub enum GameID{
Surf=2,
FlyTrials=5,
}
impl From<GameID> for submissions_api::types::GameID{
fn from(value:GameID)->Self{
match value{
GameID::Bhop=>submissions_api::types::GameID::Bhop,
GameID::Surf=>submissions_api::types::GameID::Surf,
GameID::FlyTrials=>submissions_api::types::GameID::FlyTrials,
}
}
}
#[derive(Debug)]
pub struct ParseGameIDError;
impl std::str::FromStr for GameID{

View File

@@ -1,43 +0,0 @@
use rust_grpc::validator::ResourceType;
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
pub struct MapfixID(pub(crate)u64);
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
pub struct SubmissionID(pub(crate)u64);
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
pub struct OperationID(pub(crate)u64);
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
pub struct ResourceID(pub(crate)u64);
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
pub struct ScriptID(pub(crate)u64);
pub struct StupidPolicy(pub(crate)rust_grpc::validator::Policy);
#[derive(Debug)]
pub struct StupidPolicyError;
impl TryFrom<i32> for StupidPolicy{
type Error=StupidPolicyError;
fn try_from(value:i32)->Result<Self,Self::Error>{
Ok(Self(match value{
0=>rust_grpc::validator::Policy::None,
1=>rust_grpc::validator::Policy::Allowed,
2=>rust_grpc::validator::Policy::Blocked,
3=>rust_grpc::validator::Policy::Delete,
4=>rust_grpc::validator::Policy::Replace,
_=>return Err(StupidPolicyError),
}))
}
}
#[derive(Clone,Copy,Debug)]
pub enum Resource{
Submission(SubmissionID),
Mapfix(MapfixID),
}
impl Resource{
pub fn split(self)->(ResourceType,ResourceID){
match self{
Resource::Mapfix(MapfixID(mapfix_id))=>(ResourceType::Mapfix,ResourceID(mapfix_id)),
Resource::Submission(SubmissionID(submission_id))=>(ResourceType::Submission,ResourceID(submission_id)),
}
}
}

View File

@@ -8,7 +8,7 @@ pub enum Error{
IO(std::io::Error),
Json(serde_json::Error),
Upload(rbx_asset::cookie::UploadError),
ApiActionMapfixUploaded(tonic::Status),
ApiActionMapfixUploaded(submissions_api::Error),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -41,8 +41,8 @@ impl crate::message_handler::MessageHandler{
// that's it, the database entry does not need to be changed.
// mark mapfix as uploaded, TargetAssetID is unchanged
self.mapfixes.set_status_uploaded(rust_grpc::validator::MapfixId{
id:upload_info.MapfixID,
self.api.action_mapfix_uploaded(submissions_api::types::ActionMapfixUploadedRequest{
MapfixID:upload_info.MapfixID,
}).await.map_err(Error::ApiActionMapfixUploaded)?;
Ok(())

View File

@@ -9,7 +9,7 @@ pub enum Error{
Json(serde_json::Error),
Create(rbx_asset::cookie::CreateError),
SystemTime(std::time::SystemTimeError),
ApiActionSubmissionUploaded(tonic::Status),
ApiActionSubmissionUploaded(submissions_api::Error),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -39,9 +39,9 @@ impl crate::message_handler::MessageHandler{
},model_data).await.map_err(Error::Create)?;
// note the asset id of the created model for later release, and mark the submission as uploaded
self.submissions.set_status_uploaded(rust_grpc::validator::StatusUploadedRequest{
id:upload_info.SubmissionID,
uploaded_asset_id:upload_response.AssetId,
self.api.action_submission_uploaded(submissions_api::types::ActionSubmissionUploadedRequest{
SubmissionID:upload_info.SubmissionID,
UploadedAssetID:upload_response.AssetId,
}).await.map_err(Error::ApiActionSubmissionUploaded)?;
Ok(())

View File

@@ -3,7 +3,7 @@ use crate::nats_types::ValidateMapfixRequest;
#[allow(dead_code)]
#[derive(Debug)]
pub enum Error{
ApiActionMapfixValidate(tonic::Status),
ApiActionMapfixValidate(submissions_api::Error),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -21,24 +21,24 @@ impl crate::message_handler::MessageHandler{
match &validate_result{
Ok(())=>{
// update the mapfix model status to validated
self.mapfixes.set_status_validated(rust_grpc::validator::MapfixId{
id:mapfix_id,
}).await.map_err(Error::ApiActionMapfixValidate)?;
self.api.action_mapfix_validated(
mapfix_id
).await.map_err(Error::ApiActionMapfixValidate)?;
},
Err(e)=>{
// log error
println!("[validate_mapfix] Error: {e}");
self.mapfixes.create_audit_error(
rust_grpc::validator::AuditErrorRequest{
id:mapfix_id,
error_message:e.to_string(),
self.api.create_mapfix_audit_error(
submissions_api::types::CreateMapfixAuditErrorRequest{
MapfixID:mapfix_id,
ErrorMessage:e.to_string(),
}
).await.map_err(Error::ApiActionMapfixValidate)?;
// update the mapfix model status to accepted
self.mapfixes.set_status_failed(rust_grpc::validator::MapfixId{
id:mapfix_id,
self.api.action_mapfix_accepted(submissions_api::types::ActionMapfixAcceptedRequest{
MapfixID:mapfix_id,
}).await.map_err(Error::ApiActionMapfixValidate)?;
},
}

View File

@@ -3,7 +3,7 @@ use crate::nats_types::ValidateSubmissionRequest;
#[allow(dead_code)]
#[derive(Debug)]
pub enum Error{
ApiActionSubmissionValidate(tonic::Status),
ApiActionSubmissionValidate(submissions_api::Error),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -21,24 +21,24 @@ impl crate::message_handler::MessageHandler{
match &validate_result{
Ok(())=>{
// update the submission model status to validated
self.submissions.set_status_validated(rust_grpc::validator::SubmissionId{
id:submission_id,
}).await.map_err(Error::ApiActionSubmissionValidate)?;
self.api.action_submission_validated(
submission_id
).await.map_err(Error::ApiActionSubmissionValidate)?;
},
Err(e)=>{
// log error
println!("[validate_submission] Error: {e}");
self.submissions.create_audit_error(
rust_grpc::validator::AuditErrorRequest{
id:submission_id,
error_message:e.to_string(),
self.api.create_submission_audit_error(
submissions_api::types::CreateSubmissionAuditErrorRequest{
SubmissionID:submission_id,
ErrorMessage:e.to_string(),
}
).await.map_err(Error::ApiActionSubmissionValidate)?;
// update the submission model status to accepted
self.submissions.set_status_failed(rust_grpc::validator::SubmissionId{
id:submission_id,
self.api.action_submission_accepted(submissions_api::types::ActionSubmissionAcceptedRequest{
SubmissionID:submission_id,
}).await.map_err(Error::ApiActionSubmissionValidate)?;
},
}

View File

@@ -1,20 +1,33 @@
use futures::TryStreamExt;
use rust_grpc::validator::Policy;
use submissions_api::types::Resource;
use crate::download::download_asset_version;
use crate::rbx_util::{read_dom,static_ustr,ReadDomError};
use crate::types::{MapfixID,ScriptID,StupidPolicy,StupidPolicyError,SubmissionID,Resource,ResourceID};
const SCRIPT_CONCURRENCY:usize=16;
enum Policy{
None,
Allowed,
Blocked,
Delete,
Replace(String),
}
struct NamePolicy{
name:String,
policy:Policy,
}
fn source_has_illegal_keywords(source:&str)->bool{
source.contains("getfenv")||source.contains("require")
}
fn hash_source(source:&str)->u64{
fn hash_source(source:&str)->String{
let mut hasher=siphasher::sip::SipHasher::new();
std::hash::Hasher::write(&mut hasher,source.as_bytes());
std::hash::Hasher::finish(&hasher)
let hash=std::hash::Hasher::finish(&hasher);
format!("{:016x}",hash)
}
#[allow(dead_code)]
@@ -27,18 +40,17 @@ pub enum Error{
submitted:u64,
},
ScriptFlaggedIllegalKeyword(String),
ScriptBlocked(Option<ScriptID>),
ScriptNotYetReviewed(Option<ScriptID>),
ScriptBlocked(Option<submissions_api::types::ScriptID>),
ScriptNotYetReviewed(Option<submissions_api::types::ScriptID>),
Download(crate::download::Error),
ModelFileDecode(ReadDomError),
ApiGetScriptPolicyFromHash(crate::grpc::error::ScriptPolicySingleItemError),
ApiGetScript(tonic::Status),
StupidPolicy(StupidPolicyError),
ApiCreateScript(tonic::Status),
ApiCreateScriptPolicy(tonic::Status),
ApiGetScriptFromHash(crate::grpc::error::ScriptSingleItemError),
ApiUpdateMapfixModel(tonic::Status),
ApiUpdateSubmissionModel(tonic::Status),
ApiGetScriptPolicyFromHash(submissions_api::types::ScriptPolicySingleItemError),
ApiGetScript(submissions_api::Error),
ApiCreateScript(submissions_api::Error),
ApiCreateScriptPolicy(submissions_api::Error),
ApiGetScriptFromHash(submissions_api::types::ScriptSingleItemError),
ApiUpdateMapfixModel(submissions_api::Error),
ApiUpdateSubmissionModel(submissions_api::Error),
ModelFileRootMustHaveOneChild,
ModelFileChildRefIsNil,
ModelFileEncode(rbx_binary::EncodeError),
@@ -66,7 +78,7 @@ impl From<crate::nats_types::ValidateMapfixRequest> for ValidateRequest{
ModelID:value.ModelID,
ModelVersion:value.ModelVersion,
ValidatedModelID:value.ValidatedModelID,
Resource:Resource::Mapfix(MapfixID(value.MapfixID)),
Resource:Resource::Mapfix(value.MapfixID),
}
}
}
@@ -76,27 +88,13 @@ impl From<crate::nats_types::ValidateSubmissionRequest> for ValidateRequest{
ModelID:value.ModelID,
ModelVersion:value.ModelVersion,
ValidatedModelID:value.ValidatedModelID,
Resource:Resource::Submission(SubmissionID(value.SubmissionID)),
Resource:Resource::Submission(value.SubmissionID),
}
}
}
impl crate::message_handler::MessageHandler{
pub async fn validate_inner(&self,validate_info:ValidateRequest)->Result<(),Error>{
enum OwnedPolicy{
None,
Allowed,
Blocked,
Delete,
Replace(String),
}
struct NamePolicy{
name:String,
policy:OwnedPolicy,
}
// discover asset creator and latest version
let info=self.cloud_context.get_asset_info(
rbx_asset::cloud::GetAssetLatestRequest{asset_id:validate_info.ModelID}
@@ -146,7 +144,7 @@ impl crate::message_handler::MessageHandler{
// policy will be fetched from the database to replace the default policy
script_map.insert(source.clone(),NamePolicy{
name:get_partial_path(&dom,script),
policy:OwnedPolicy::None,
policy:Policy::None,
});
}
}
@@ -159,42 +157,40 @@ impl crate::message_handler::MessageHandler{
let hash=hash_source(source.as_str());
// fetch the script policy
let script_policy=self.script_policy.get_from_hash(
hash,
).await.map_err(Error::ApiGetScriptPolicyFromHash)?;
let script_policy=self.api.get_script_policy_from_hash(submissions_api::types::HashRequest{
hash:hash.as_str(),
}).await.map_err(Error::ApiGetScriptPolicyFromHash)?;
// write the policy to the script_map, fetching the replacement code if necessary
if let Some(script_policy)=script_policy{
*policy=match script_policy.policy.try_into(){
Ok(StupidPolicy(Policy::None))=>OwnedPolicy::None,
Ok(StupidPolicy(Policy::Allowed))=>OwnedPolicy::Allowed,
Ok(StupidPolicy(Policy::Blocked))=>OwnedPolicy::Blocked,
Ok(StupidPolicy(Policy::Delete))=>OwnedPolicy::Delete,
Ok(StupidPolicy(Policy::Replace))=>{
let script=self.scripts.get(rust_grpc::validator::ScriptId{
id:script_policy.to_script_id,
*policy=match script_policy.Policy{
submissions_api::types::Policy::None=>Policy::None,
submissions_api::types::Policy::Allowed=>Policy::Allowed,
submissions_api::types::Policy::Blocked=>Policy::Blocked,
submissions_api::types::Policy::Delete=>Policy::Delete,
submissions_api::types::Policy::Replace=>{
let script=self.api.get_script(submissions_api::types::GetScriptRequest{
ScriptID:script_policy.ToScriptID,
}).await.map_err(Error::ApiGetScript)?;
OwnedPolicy::Replace(script.source)
Policy::Replace(script.Source)
},
// WHY DOES PROTOBUF NOT HAVE EMBEDDED ENUMS
Err(e)=>return Err(Error::StupidPolicy(e)),
};
}else{
let (resource_type,ResourceID(resource_id))=validate_info.Resource.split();
let (resource_type,resource_id)=validate_info.Resource.split();
// upload the script
let script=self.scripts.create(rust_grpc::validator::ScriptCreate{
name:name.clone(),
source:source.clone(),
resource_type:resource_type as i32,
resource_id:Some(resource_id),
let script=self.api.create_script(submissions_api::types::CreateScriptRequest{
Name:name.as_str(),
Source:source.as_str(),
ResourceType:resource_type,
ResourceID:Some(resource_id),
}).await.map_err(Error::ApiCreateScript)?;
// create a None policy (pending review by yours truly)
self.script_policy.create(rust_grpc::validator::ScriptPolicyCreate{
to_script_id:script.id,
from_script_id:script.id,
policy:rust_grpc::validator::Policy::None as i32,
self.api.create_script_policy(submissions_api::types::CreateScriptPolicyRequest{
ToScriptID:script.ScriptID,
FromScriptID:script.ScriptID,
Policy:submissions_api::types::Policy::None,
}).await.map_err(Error::ApiCreateScriptPolicy)?;
}
@@ -208,29 +204,29 @@ impl crate::message_handler::MessageHandler{
if let Some(script)=dom.get_by_ref_mut(script_ref){
if let Some(rbx_dom_weak::types::Variant::String(source))=script.properties.get_mut(&source_property){
match script_map.get(source.as_str()).map(|p|&p.policy){
Some(OwnedPolicy::Blocked)=>{
Some(Policy::Blocked)=>{
let hash=hash_source(source.as_str());
let script=self.scripts.get_from_hash(
hash,
).await.map_err(Error::ApiGetScriptFromHash)?;
return Err(Error::ScriptBlocked(script.map(|s|ScriptID(s.id))));
let script=self.api.get_script_from_hash(submissions_api::types::HashRequest{
hash:hash.as_str(),
}).await.map_err(Error::ApiGetScriptFromHash)?;
return Err(Error::ScriptBlocked(script.map(|s|s.ID)));
},
None
|Some(OwnedPolicy::None)
|Some(Policy::None)
=>{
let hash=hash_source(source.as_str());
let script=self.scripts.get_from_hash(
hash,
).await.map_err(Error::ApiGetScriptFromHash)?;
return Err(Error::ScriptNotYetReviewed(script.map(|s|ScriptID(s.id))));
let script=self.api.get_script_from_hash(submissions_api::types::HashRequest{
hash:hash.as_str(),
}).await.map_err(Error::ApiGetScriptFromHash)?;
return Err(Error::ScriptNotYetReviewed(script.map(|s|s.ID)));
},
Some(OwnedPolicy::Allowed)=>(),
Some(OwnedPolicy::Delete)=>{
Some(Policy::Allowed)=>(),
Some(Policy::Delete)=>{
modified=true;
// delete script
dom.destroy(script_ref);
},
Some(OwnedPolicy::Replace(replacement))=>{
Some(Policy::Replace(replacement))=>{
modified=true;
*source=replacement.clone();
},
@@ -282,20 +278,20 @@ impl crate::message_handler::MessageHandler{
};
match validate_info.Resource{
Resource::Mapfix(MapfixID(mapfix_id))=>{
Resource::Mapfix(mapfix_id)=>{
// update the mapfix to use the validated model
self.mapfixes.set_validated_model(rust_grpc::validator::ValidatedModelRequest{
id:mapfix_id,
validated_model_id,
validated_model_version,
self.api.update_mapfix_validated_model(submissions_api::types::UpdateMapfixModelRequest{
MapfixID:mapfix_id,
ModelID:validated_model_id,
ModelVersion:validated_model_version,
}).await.map_err(Error::ApiUpdateMapfixModel)?;
},
Resource::Submission(SubmissionID(submission_id))=>{
Resource::Submission(submission_id)=>{
// update the submission to use the validated model
self.submissions.set_validated_model(rust_grpc::validator::ValidatedModelRequest{
id:submission_id,
validated_model_id,
validated_model_version,
self.api.update_submission_validated_model(submissions_api::types::UpdateSubmissionModelRequest{
SubmissionID:submission_id,
ModelID:validated_model_id,
ModelVersion:validated_model_version,
}).await.map_err(Error::ApiUpdateSubmissionModel)?;
},
}