forked from StrafesNET/maps-service
Compare commits
126 Commits
debug-auth
...
validator-
| Author | SHA1 | Date | |
|---|---|---|---|
|
84299675ff
|
|||
|
dd698528be
|
|||
|
01785bb190
|
|||
|
8366b84d90
|
|||
|
746c7aa9b7
|
|||
|
930eb47096
|
|||
|
9671c357f4
|
|||
|
3404251c14
|
|||
|
ffcba57408
|
|||
|
a60ccd22f0
|
|||
|
f7d7a0891d
|
|||
|
e5e85db1fd
|
|||
|
0b64440975
|
|||
|
0e29ca98dd
|
|||
|
9740cbe91a
|
|||
|
2d2691b551
|
|||
|
dfc2a605f4
|
|||
|
88c3866654
|
|||
|
92226e768d
|
|||
|
4515eb6da2
|
|||
|
f2d8c49647
|
|||
|
2c75cfa67f
|
|||
|
f3689f4916
|
|||
|
e855ace229
|
|||
|
6e21447d4b
|
|||
| 49fea314ec | |||
| 4c17a3c9e9 | |||
| a7784bdaf5 | |||
|
f0e18a5963
|
|||
|
661fa17fa7
|
|||
|
cc1d5f4bda
|
|||
|
e7a66ebe0d
|
|||
|
977f3902b7
|
|||
| af9f413b49 | |||
| b02b3d205e | |||
|
2f2241612a
|
|||
|
a7c72163eb
|
|||
|
c8077482f3
|
|||
|
79c21b62d8
|
|||
|
032f0e8739
|
|||
|
251a24efae
|
|||
|
a9afdf38cf
|
|||
|
d3edb6b3da
|
|||
|
188fbd2a6d
|
|||
|
1468a9edc2
|
|||
|
1053719eab
|
|||
|
2867da4b21
|
|||
|
85a144e276
|
|||
| 4227f18992 | |||
| 123bc8af47 | |||
| cd82954b73 | |||
| ce08b57e18 | |||
| 1ca0348924 | |||
| 936a1f93aa | |||
| d5d0e5ffc9 | |||
|
039309c75a
|
|||
|
7cc0b5da7f
|
|||
|
f0c44fb4a8
|
|||
|
4fec1bba47
|
|||
|
5ae287f3f2
|
|||
|
bf6c8af21a
|
|||
|
65e63431a3
|
|||
|
a8dc6cd35a
|
|||
|
539e09fe06
|
|||
|
87fd7adb93
|
|||
|
7d57d1ac4d
|
|||
|
636bb1fb94
|
|||
|
295ec3cd8b
|
|||
|
6af006f802
|
|||
|
d16bb8ad02
|
|||
|
1af7d7e941
|
|||
|
1feca92f7d
|
|||
|
7213948a26
|
|||
|
783d0e843c
|
|||
|
977d1d20c2
|
|||
|
d7634de9ec
|
|||
|
8da1c9346b
|
|||
|
894851c0e8
|
|||
| 3da4023466 | |||
| 08a4e913a9 | |||
| 6748cb4324 | |||
| 73e5c76e75 | |||
| b4be174d98 | |||
| f52e0a91a2 | |||
| 0b1e7085e3 | |||
| 31f1db6446 | |||
| b377405762 | |||
| b496f8c0d8 | |||
| 0c247fbb43 | |||
| 483ffd1d66 | |||
| ff01abdd63 | |||
| 0271ba4d28 | |||
| c6b31b7c73 | |||
| 80e7d735be | |||
| e66513e88d | |||
| 355161c3b1 | |||
| e5a1dcf144 | |||
| 99e320d17f | |||
| 57d714fdd7 | |||
| d77bf02185 | |||
| 47129e2d1f | |||
| b542dba739 | |||
| f5c4868dc4 | |||
| 1341f87bf8 | |||
| 57544f3f64 | |||
| ecb88c14a4 | |||
| e1645e7c46 | |||
| 49e767f027 | |||
| 91a72ccf8b | |||
| 11e801443f | |||
| 8338a71470 | |||
| 59e5e529c6 | |||
| a82a78c938 | |||
| b6c7c76900 | |||
| 75e8d2b7b2 | |||
| 8dbdfbdb3f | |||
| 28990e2dbe | |||
| a39e2892ef | |||
| 8e223d432e | |||
|
|
040488d85f | ||
| e43f4bd0f0 | |||
| ca1e007b07 | |||
| 952ceab014 | |||
| 952b77b3db | |||
| 0794e7ba46 | |||
| bc8b7b68d2 |
@@ -67,7 +67,10 @@ steps:
|
|||||||
- name: deploy
|
- name: deploy
|
||||||
image: argoproj/argocd:latest
|
image: argoproj/argocd:latest
|
||||||
commands:
|
commands:
|
||||||
- echo "Deploy!" # Not going to do actually do this until
|
- argocd login --grpc-web cd.stricity.com --username $USERNAME --password $PASSWORD
|
||||||
|
- argocd app --grpc-web set ${DRONE_BRANCH}-maps-service --kustomize-image registry.itzana.me/strafesnet/maptest-api:${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
|
||||||
|
- argocd app --grpc-web set ${DRONE_BRANCH}-maps-service --kustomize-image registry.itzana.me/strafesnet/maptest-frontend:${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
|
||||||
|
- argocd app --grpc-web set ${DRONE_BRANCH}-maps-service --kustomize-image registry.itzana.me/strafesnet/maptest-validator:${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
|
||||||
environment:
|
environment:
|
||||||
USERNAME:
|
USERNAME:
|
||||||
from_secret: ARGO_USER
|
from_secret: ARGO_USER
|
||||||
@@ -83,6 +86,6 @@ steps:
|
|||||||
- staging
|
- staging
|
||||||
---
|
---
|
||||||
kind: signature
|
kind: signature
|
||||||
hmac: 9958fd5b01af1ebcc75f7277fe71eb5336b899445c359cecf1b14e83b3d05059
|
hmac: 1162b329a9cad12b4c5db0ccf8b8998072b0de9279326f76a493fd0af6794095
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
.idea
|
.idea
|
||||||
|
/target
|
||||||
|
|||||||
630
validation/Cargo.lock → Cargo.lock
generated
630
validation/Cargo.lock → Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"validation",
|
||||||
|
"validation/api",
|
||||||
|
]
|
||||||
|
resolver = "2"
|
||||||
12
README.md
12
README.md
@@ -26,6 +26,12 @@ Prerequisite: golang installed
|
|||||||
|
|
||||||
Prerequisite: bun installed
|
Prerequisite: bun installed
|
||||||
|
|
||||||
|
The environment variable `API_HOST` will need to be set for the middleware.
|
||||||
|
Example `.env` in web's root:
|
||||||
|
```
|
||||||
|
API_HOST="http://localhost:8082/v1/"
|
||||||
|
```
|
||||||
|
|
||||||
1. `cd web`
|
1. `cd web`
|
||||||
2. `bun install`
|
2. `bun install`
|
||||||
|
|
||||||
@@ -43,6 +49,12 @@ Prerequisite: rust installed
|
|||||||
1. `cd validation`
|
1. `cd validation`
|
||||||
2. `cargo run --release`
|
2. `cargo run --release`
|
||||||
|
|
||||||
|
Environment Variables:
|
||||||
|
- ROBLOX_GROUP_ID
|
||||||
|
- RBXCOOKIE
|
||||||
|
- API_HOST_INTERNAL
|
||||||
|
- NATS_HOST
|
||||||
|
|
||||||
#### License
|
#### License
|
||||||
|
|
||||||
<sup>
|
<sup>
|
||||||
|
|||||||
13
compose.yaml
13
compose.yaml
@@ -30,7 +30,8 @@ services:
|
|||||||
"--pg-password","happypostgresuser",
|
"--pg-password","happypostgresuser",
|
||||||
# other hosts
|
# other hosts
|
||||||
"--nats-host","nats:4222",
|
"--nats-host","nats:4222",
|
||||||
"--auth-rpc-host","authrpc:8081"
|
"--auth-rpc-host","authrpc:8081",
|
||||||
|
"--data-rpc-host","dataservice:9000",
|
||||||
]
|
]
|
||||||
depends_on:
|
depends_on:
|
||||||
- authrpc
|
- authrpc
|
||||||
@@ -47,6 +48,8 @@ services:
|
|||||||
- maps-service-network
|
- maps-service-network
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- API_HOST=http://submissions:8082/v1
|
||||||
|
|
||||||
validation:
|
validation:
|
||||||
image:
|
image:
|
||||||
@@ -56,9 +59,8 @@ services:
|
|||||||
- ../auth-compose/strafesnet_staging.env
|
- ../auth-compose/strafesnet_staging.env
|
||||||
environment:
|
environment:
|
||||||
- ROBLOX_GROUP_ID=17032139 # "None" is special case string value
|
- ROBLOX_GROUP_ID=17032139 # "None" is special case string value
|
||||||
- API_HOST_INTERNAL=http://submissions:8083
|
- API_HOST_INTERNAL=http://submissions:8083/v1
|
||||||
- NATS_HOST=nats:4222
|
- NATS_HOST=nats:4222
|
||||||
- DATA_HOST=http://dataservice:9000
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- nats
|
- nats
|
||||||
# note: this races the submissions which creates a nats stream
|
# note: this races the submissions which creates a nats stream
|
||||||
@@ -91,11 +93,12 @@ services:
|
|||||||
- maps-service-network
|
- maps-service-network
|
||||||
|
|
||||||
authrpc:
|
authrpc:
|
||||||
image: registry.itzana.me/strafesnet/auth-service:master
|
image: registry.itzana.me/strafesnet/auth-service:staging
|
||||||
container_name: authrpc
|
container_name: authrpc
|
||||||
command: ["serve", "rpc"]
|
command: ["serve", "rpc"]
|
||||||
environment:
|
environment:
|
||||||
- REDIS_ADDR=authredis:6379
|
- REDIS_ADDR=authredis:6379
|
||||||
|
- RBX_GROUP_ID=17032139
|
||||||
env_file:
|
env_file:
|
||||||
- ../auth-compose/auth-service.env
|
- ../auth-compose/auth-service.env
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -106,7 +109,7 @@ services:
|
|||||||
driver: "none"
|
driver: "none"
|
||||||
|
|
||||||
auth-web:
|
auth-web:
|
||||||
image: registry.itzana.me/strafesnet/auth-service:master
|
image: registry.itzana.me/strafesnet/auth-service:staging
|
||||||
command: ["serve", "web"]
|
command: ["serve", "web"]
|
||||||
environment:
|
environment:
|
||||||
- REDIS_ADDR=authredis:6379
|
- REDIS_ADDR=authredis:6379
|
||||||
|
|||||||
@@ -7,21 +7,21 @@ tags:
|
|||||||
- name: Submissions
|
- name: Submissions
|
||||||
description: Submission operations
|
description: Submission operations
|
||||||
paths:
|
paths:
|
||||||
/submissions/{SubmissionID}/model:
|
/submissions/{SubmissionID}/validated-model:
|
||||||
post:
|
post:
|
||||||
summary: Update model following role restrictions
|
summary: Update validated model
|
||||||
operationId: updateSubmissionModel
|
operationId: updateSubmissionValidatedModel
|
||||||
tags:
|
tags:
|
||||||
- Submissions
|
- Submissions
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/SubmissionID'
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
- name: ModelID
|
- name: ValidatedModelID
|
||||||
in: query
|
in: query
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
- name: VersionID
|
- name: ValidatedModelVersion
|
||||||
in: query
|
in: query
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
@@ -61,6 +61,13 @@ paths:
|
|||||||
- Submissions
|
- Submissions
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/SubmissionID'
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
|
- name: StatusMessage
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 0
|
||||||
|
maxLength: 4096
|
||||||
responses:
|
responses:
|
||||||
"204":
|
"204":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -78,8 +85,9 @@ paths:
|
|||||||
- Submissions
|
- Submissions
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/SubmissionID'
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
- name: TargetAssetID
|
- name: UploadedAssetID
|
||||||
in: query
|
in: query
|
||||||
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
@@ -92,23 +100,6 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
/submissions/{SubmissionID}/status/releaser-released:
|
|
||||||
post:
|
|
||||||
summary: (Internal endpoint) Role Releaser changes status from releasing -> released
|
|
||||||
operationId: actionSubmissionReleased
|
|
||||||
tags:
|
|
||||||
- Submissions
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/SubmissionID'
|
|
||||||
responses:
|
|
||||||
"204":
|
|
||||||
description: Successful response
|
|
||||||
default:
|
|
||||||
description: General Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: "#/components/schemas/Error"
|
|
||||||
/script-policy:
|
/script-policy:
|
||||||
get:
|
get:
|
||||||
summary: Get list of script policies
|
summary: Get list of script policies
|
||||||
@@ -313,7 +304,8 @@ components:
|
|||||||
- Name
|
- Name
|
||||||
- Hash
|
- Hash
|
||||||
- Source
|
- Source
|
||||||
- SubmissionID
|
- ResourceType
|
||||||
|
- ResourceID
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
ID:
|
ID:
|
||||||
@@ -329,14 +321,18 @@ components:
|
|||||||
Source:
|
Source:
|
||||||
type: string
|
type: string
|
||||||
maxLength: 1048576
|
maxLength: 1048576
|
||||||
SubmissionID:
|
ResourceType:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ResourceID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
ScriptCreate:
|
ScriptCreate:
|
||||||
required:
|
required:
|
||||||
- Name
|
- Name
|
||||||
- Source
|
- Source
|
||||||
# - SubmissionID
|
- ResourceType
|
||||||
|
# - ResourceID
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
Name:
|
Name:
|
||||||
@@ -345,7 +341,10 @@ components:
|
|||||||
Source:
|
Source:
|
||||||
type: string
|
type: string
|
||||||
maxLength: 1048576
|
maxLength: 1048576
|
||||||
SubmissionID:
|
ResourceType:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ResourceID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
ScriptPolicy:
|
ScriptPolicy:
|
||||||
|
|||||||
219
openapi.yaml
219
openapi.yaml
@@ -6,6 +6,8 @@ info:
|
|||||||
servers:
|
servers:
|
||||||
- url: https://submissions.strafes.net/v1
|
- url: https://submissions.strafes.net/v1
|
||||||
tags:
|
tags:
|
||||||
|
- name: Session
|
||||||
|
description: Session operations
|
||||||
- name: Submissions
|
- name: Submissions
|
||||||
description: Submission operations
|
description: Submission operations
|
||||||
- name: Scripts
|
- name: Scripts
|
||||||
@@ -15,12 +17,70 @@ tags:
|
|||||||
security:
|
security:
|
||||||
- cookieAuth: []
|
- cookieAuth: []
|
||||||
paths:
|
paths:
|
||||||
|
/session/user:
|
||||||
|
get:
|
||||||
|
summary: Get information about the currently logged in user
|
||||||
|
operationId: sessionUser
|
||||||
|
tags:
|
||||||
|
- Session
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/User"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/session/roles:
|
||||||
|
get:
|
||||||
|
summary: Get list of roles for the current session
|
||||||
|
operationId: sessionRoles
|
||||||
|
tags:
|
||||||
|
- Session
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Roles"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/session/validate:
|
||||||
|
get:
|
||||||
|
summary: Ask if the current session is valid
|
||||||
|
operationId: sessionValidate
|
||||||
|
tags:
|
||||||
|
- Session
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
/submissions:
|
/submissions:
|
||||||
get:
|
get:
|
||||||
summary: Get list of submissions
|
summary: Get list of submissions
|
||||||
operationId: listSubmissions
|
operationId: listSubmissions
|
||||||
tags:
|
tags:
|
||||||
- Submissions
|
- Submissions
|
||||||
|
security: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/Page"
|
- $ref: "#/components/parameters/Page"
|
||||||
- $ref: "#/components/parameters/Limit"
|
- $ref: "#/components/parameters/Limit"
|
||||||
@@ -39,6 +99,11 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
|
- name: Sort
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -84,6 +149,7 @@ paths:
|
|||||||
operationId: getSubmission
|
operationId: getSubmission
|
||||||
tags:
|
tags:
|
||||||
- Submissions
|
- Submissions
|
||||||
|
security: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/SubmissionID'
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
responses:
|
responses:
|
||||||
@@ -130,7 +196,7 @@ paths:
|
|||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
/submissions/{SubmissionID}/completed:
|
/submissions/{SubmissionID}/completed:
|
||||||
post:
|
post:
|
||||||
summary: Retrieve map with ID
|
summary: Called by maptest when a player completes the map
|
||||||
operationId: setSubmissionCompleted
|
operationId: setSubmissionCompleted
|
||||||
tags:
|
tags:
|
||||||
- Submissions
|
- Submissions
|
||||||
@@ -181,7 +247,7 @@ paths:
|
|||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
/submissions/{SubmissionID}/status/trigger-validate:
|
/submissions/{SubmissionID}/status/trigger-validate:
|
||||||
post:
|
post:
|
||||||
summary: Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating
|
summary: Role Reviewer triggers validation and changes status from Submitted -> Validating
|
||||||
operationId: actionSubmissionTriggerValidate
|
operationId: actionSubmissionTriggerValidate
|
||||||
tags:
|
tags:
|
||||||
- Submissions
|
- Submissions
|
||||||
@@ -196,6 +262,40 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions/{SubmissionID}/status/retry-validate:
|
||||||
|
post:
|
||||||
|
summary: Role Reviewer re-runs validation and changes status from Accepted -> Validating
|
||||||
|
operationId: actionSubmissionRetryValidate
|
||||||
|
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/reset-validating:
|
||||||
|
post:
|
||||||
|
summary: Role Reviewer manually resets validating softlock and 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/reject:
|
/submissions/{SubmissionID}/status/reject:
|
||||||
post:
|
post:
|
||||||
summary: Role Reviewer changes status from Submitted -> Rejected
|
summary: Role Reviewer changes status from Submitted -> Rejected
|
||||||
@@ -247,12 +347,55 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions/{SubmissionID}/status/reset-uploading:
|
||||||
|
post:
|
||||||
|
summary: Role Admin manually resets uploading softlock and changes status from Uploading -> 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"
|
||||||
|
/release-submissions:
|
||||||
|
post:
|
||||||
|
summary: Release a set of uploaded maps
|
||||||
|
operationId: releaseSubmissions
|
||||||
|
tags:
|
||||||
|
- Submissions
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 255
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/ReleaseInfo'
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
/script-policy:
|
/script-policy:
|
||||||
get:
|
get:
|
||||||
summary: Get list of script policies
|
summary: Get list of script policies
|
||||||
operationId: listScriptPolicy
|
operationId: listScriptPolicy
|
||||||
tags:
|
tags:
|
||||||
- ScriptPolicy
|
- ScriptPolicy
|
||||||
|
security: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/Page"
|
- $ref: "#/components/parameters/Page"
|
||||||
- $ref: "#/components/parameters/Limit"
|
- $ref: "#/components/parameters/Limit"
|
||||||
@@ -317,6 +460,7 @@ paths:
|
|||||||
operationId: getScriptPolicy
|
operationId: getScriptPolicy
|
||||||
tags:
|
tags:
|
||||||
- ScriptPolicy
|
- ScriptPolicy
|
||||||
|
security: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/ScriptPolicyID'
|
- $ref: '#/components/parameters/ScriptPolicyID'
|
||||||
responses:
|
responses:
|
||||||
@@ -376,6 +520,7 @@ paths:
|
|||||||
operationId: listScripts
|
operationId: listScripts
|
||||||
tags:
|
tags:
|
||||||
- Script
|
- Script
|
||||||
|
security: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/Page"
|
- $ref: "#/components/parameters/Page"
|
||||||
- $ref: "#/components/parameters/Limit"
|
- $ref: "#/components/parameters/Limit"
|
||||||
@@ -445,6 +590,7 @@ paths:
|
|||||||
operationId: getScript
|
operationId: getScript
|
||||||
tags:
|
tags:
|
||||||
- Scripts
|
- Scripts
|
||||||
|
security: []
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/ScriptID'
|
- $ref: '#/components/parameters/ScriptID'
|
||||||
responses:
|
responses:
|
||||||
@@ -555,6 +701,30 @@ components:
|
|||||||
ID:
|
ID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
Roles:
|
||||||
|
required:
|
||||||
|
- Roles
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
Roles:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
User:
|
||||||
|
required:
|
||||||
|
- UserID
|
||||||
|
- Username
|
||||||
|
- AvatarURL
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
UserID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
Username:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
AvatarURL:
|
||||||
|
type: string
|
||||||
|
maxLength: 256
|
||||||
Submission:
|
Submission:
|
||||||
required:
|
required:
|
||||||
- ID
|
- ID
|
||||||
@@ -567,9 +737,9 @@ components:
|
|||||||
- AssetID
|
- AssetID
|
||||||
- AssetVersion
|
- AssetVersion
|
||||||
- Completed
|
- Completed
|
||||||
- SubmissionType
|
# - UploadedAssetID
|
||||||
# - TargetAssetID
|
|
||||||
- StatusID
|
- StatusID
|
||||||
|
- StatusMessage
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
ID:
|
ID:
|
||||||
@@ -601,15 +771,15 @@ components:
|
|||||||
format: int64
|
format: int64
|
||||||
Completed:
|
Completed:
|
||||||
type: boolean
|
type: boolean
|
||||||
SubmissionType:
|
UploadedAssetID:
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
TargetAssetID:
|
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
StatusID:
|
StatusID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
|
StatusMessage:
|
||||||
|
type: string
|
||||||
|
maxLength: 256
|
||||||
SubmissionCreate:
|
SubmissionCreate:
|
||||||
required:
|
required:
|
||||||
- DisplayName
|
- DisplayName
|
||||||
@@ -617,7 +787,6 @@ components:
|
|||||||
- GameID
|
- GameID
|
||||||
- AssetID
|
- AssetID
|
||||||
- AssetVersion
|
- AssetVersion
|
||||||
# - TargetAssetID
|
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
DisplayName:
|
DisplayName:
|
||||||
@@ -635,16 +804,26 @@ components:
|
|||||||
AssetVersion:
|
AssetVersion:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
TargetAssetID:
|
ReleaseInfo:
|
||||||
|
required:
|
||||||
|
- SubmissionID
|
||||||
|
- Date
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
SubmissionID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
Date:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
Script:
|
Script:
|
||||||
required:
|
required:
|
||||||
- ID
|
- ID
|
||||||
- Name
|
- Name
|
||||||
- Hash
|
- Hash
|
||||||
- Source
|
- Source
|
||||||
- SubmissionID
|
- ResourceType
|
||||||
|
- ResourceID
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
ID:
|
ID:
|
||||||
@@ -660,14 +839,18 @@ components:
|
|||||||
Source:
|
Source:
|
||||||
type: string
|
type: string
|
||||||
maxLength: 1048576
|
maxLength: 1048576
|
||||||
SubmissionID:
|
ResourceType:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ResourceID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
ScriptCreate:
|
ScriptCreate:
|
||||||
required:
|
required:
|
||||||
- Name
|
- Name
|
||||||
- Source
|
- Source
|
||||||
# - SubmissionID
|
- ResourceType
|
||||||
|
# - ResourceID
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
Name:
|
Name:
|
||||||
@@ -676,7 +859,10 @@ components:
|
|||||||
Source:
|
Source:
|
||||||
type: string
|
type: string
|
||||||
maxLength: 1048576
|
maxLength: 1048576
|
||||||
SubmissionID:
|
ResourceType:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ResourceID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
ScriptUpdate:
|
ScriptUpdate:
|
||||||
@@ -693,7 +879,10 @@ components:
|
|||||||
Source:
|
Source:
|
||||||
type: string
|
type: string
|
||||||
maxLength: 1048576
|
maxLength: 1048576
|
||||||
SubmissionID:
|
ResourceType:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ResourceID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
ScriptPolicy:
|
ScriptPolicy:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/go-faster/errors"
|
"github.com/go-faster/errors"
|
||||||
"github.com/go-faster/jx"
|
"github.com/go-faster/jx"
|
||||||
|
|
||||||
|
"github.com/ogen-go/ogen/json"
|
||||||
"github.com/ogen-go/ogen/validate"
|
"github.com/ogen-go/ogen/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -326,6 +327,215 @@ func (s *OptString) UnmarshalJSON(data []byte) error {
|
|||||||
return s.Decode(d)
|
return s.Decode(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode implements json.Marshaler.
|
||||||
|
func (s *ReleaseInfo) Encode(e *jx.Encoder) {
|
||||||
|
e.ObjStart()
|
||||||
|
s.encodeFields(e)
|
||||||
|
e.ObjEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeFields encodes fields.
|
||||||
|
func (s *ReleaseInfo) encodeFields(e *jx.Encoder) {
|
||||||
|
{
|
||||||
|
e.FieldStart("SubmissionID")
|
||||||
|
e.Int64(s.SubmissionID)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("Date")
|
||||||
|
json.EncodeDateTime(e, s.Date)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonFieldsNameOfReleaseInfo = [2]string{
|
||||||
|
0: "SubmissionID",
|
||||||
|
1: "Date",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decodes ReleaseInfo from json.
|
||||||
|
func (s *ReleaseInfo) Decode(d *jx.Decoder) error {
|
||||||
|
if s == nil {
|
||||||
|
return errors.New("invalid: unable to decode ReleaseInfo to nil")
|
||||||
|
}
|
||||||
|
var requiredBitSet [1]uint8
|
||||||
|
|
||||||
|
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
|
||||||
|
switch string(k) {
|
||||||
|
case "SubmissionID":
|
||||||
|
requiredBitSet[0] |= 1 << 0
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Int64()
|
||||||
|
s.SubmissionID = int64(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"SubmissionID\"")
|
||||||
|
}
|
||||||
|
case "Date":
|
||||||
|
requiredBitSet[0] |= 1 << 1
|
||||||
|
if err := func() error {
|
||||||
|
v, err := json.DecodeDateTime(d)
|
||||||
|
s.Date = v
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"Date\"")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return d.Skip()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return errors.Wrap(err, "decode ReleaseInfo")
|
||||||
|
}
|
||||||
|
// Validate required fields.
|
||||||
|
var failures []validate.FieldError
|
||||||
|
for i, mask := range [1]uint8{
|
||||||
|
0b00000011,
|
||||||
|
} {
|
||||||
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
|
//
|
||||||
|
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
|
||||||
|
// Bits of fields which would be set are actually bits of missed fields.
|
||||||
|
missed := bits.OnesCount8(result)
|
||||||
|
for bitN := 0; bitN < missed; bitN++ {
|
||||||
|
bitIdx := bits.TrailingZeros8(result)
|
||||||
|
fieldIdx := i*8 + bitIdx
|
||||||
|
var name string
|
||||||
|
if fieldIdx < len(jsonFieldsNameOfReleaseInfo) {
|
||||||
|
name = jsonFieldsNameOfReleaseInfo[fieldIdx]
|
||||||
|
} else {
|
||||||
|
name = strconv.Itoa(fieldIdx)
|
||||||
|
}
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: name,
|
||||||
|
Error: validate.ErrFieldRequired,
|
||||||
|
})
|
||||||
|
// Reset bit.
|
||||||
|
result &^= 1 << bitIdx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements stdjson.Marshaler.
|
||||||
|
func (s *ReleaseInfo) MarshalJSON() ([]byte, error) {
|
||||||
|
e := jx.Encoder{}
|
||||||
|
s.Encode(&e)
|
||||||
|
return e.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements stdjson.Unmarshaler.
|
||||||
|
func (s *ReleaseInfo) UnmarshalJSON(data []byte) error {
|
||||||
|
d := jx.DecodeBytes(data)
|
||||||
|
return s.Decode(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode implements json.Marshaler.
|
||||||
|
func (s *Roles) Encode(e *jx.Encoder) {
|
||||||
|
e.ObjStart()
|
||||||
|
s.encodeFields(e)
|
||||||
|
e.ObjEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeFields encodes fields.
|
||||||
|
func (s *Roles) encodeFields(e *jx.Encoder) {
|
||||||
|
{
|
||||||
|
e.FieldStart("Roles")
|
||||||
|
e.Int32(s.Roles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonFieldsNameOfRoles = [1]string{
|
||||||
|
0: "Roles",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decodes Roles from json.
|
||||||
|
func (s *Roles) Decode(d *jx.Decoder) error {
|
||||||
|
if s == nil {
|
||||||
|
return errors.New("invalid: unable to decode Roles to nil")
|
||||||
|
}
|
||||||
|
var requiredBitSet [1]uint8
|
||||||
|
|
||||||
|
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
|
||||||
|
switch string(k) {
|
||||||
|
case "Roles":
|
||||||
|
requiredBitSet[0] |= 1 << 0
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Int32()
|
||||||
|
s.Roles = int32(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"Roles\"")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return d.Skip()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return errors.Wrap(err, "decode Roles")
|
||||||
|
}
|
||||||
|
// Validate required fields.
|
||||||
|
var failures []validate.FieldError
|
||||||
|
for i, mask := range [1]uint8{
|
||||||
|
0b00000001,
|
||||||
|
} {
|
||||||
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
|
//
|
||||||
|
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
|
||||||
|
// Bits of fields which would be set are actually bits of missed fields.
|
||||||
|
missed := bits.OnesCount8(result)
|
||||||
|
for bitN := 0; bitN < missed; bitN++ {
|
||||||
|
bitIdx := bits.TrailingZeros8(result)
|
||||||
|
fieldIdx := i*8 + bitIdx
|
||||||
|
var name string
|
||||||
|
if fieldIdx < len(jsonFieldsNameOfRoles) {
|
||||||
|
name = jsonFieldsNameOfRoles[fieldIdx]
|
||||||
|
} else {
|
||||||
|
name = strconv.Itoa(fieldIdx)
|
||||||
|
}
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: name,
|
||||||
|
Error: validate.ErrFieldRequired,
|
||||||
|
})
|
||||||
|
// Reset bit.
|
||||||
|
result &^= 1 << bitIdx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements stdjson.Marshaler.
|
||||||
|
func (s *Roles) MarshalJSON() ([]byte, error) {
|
||||||
|
e := jx.Encoder{}
|
||||||
|
s.Encode(&e)
|
||||||
|
return e.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements stdjson.Unmarshaler.
|
||||||
|
func (s *Roles) UnmarshalJSON(data []byte) error {
|
||||||
|
d := jx.DecodeBytes(data)
|
||||||
|
return s.Decode(d)
|
||||||
|
}
|
||||||
|
|
||||||
// Encode implements json.Marshaler.
|
// Encode implements json.Marshaler.
|
||||||
func (s *Script) Encode(e *jx.Encoder) {
|
func (s *Script) Encode(e *jx.Encoder) {
|
||||||
e.ObjStart()
|
e.ObjStart()
|
||||||
@@ -352,17 +562,22 @@ func (s *Script) encodeFields(e *jx.Encoder) {
|
|||||||
e.Str(s.Source)
|
e.Str(s.Source)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
e.FieldStart("SubmissionID")
|
e.FieldStart("ResourceType")
|
||||||
e.Int64(s.SubmissionID)
|
e.Int32(s.ResourceType)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("ResourceID")
|
||||||
|
e.Int64(s.ResourceID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfScript = [5]string{
|
var jsonFieldsNameOfScript = [6]string{
|
||||||
0: "ID",
|
0: "ID",
|
||||||
1: "Name",
|
1: "Name",
|
||||||
2: "Hash",
|
2: "Hash",
|
||||||
3: "Source",
|
3: "Source",
|
||||||
4: "SubmissionID",
|
4: "ResourceType",
|
||||||
|
5: "ResourceID",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes Script from json.
|
// Decode decodes Script from json.
|
||||||
@@ -422,17 +637,29 @@ func (s *Script) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"Source\"")
|
return errors.Wrap(err, "decode field \"Source\"")
|
||||||
}
|
}
|
||||||
case "SubmissionID":
|
case "ResourceType":
|
||||||
requiredBitSet[0] |= 1 << 4
|
requiredBitSet[0] |= 1 << 4
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
v, err := d.Int64()
|
v, err := d.Int32()
|
||||||
s.SubmissionID = int64(v)
|
s.ResourceType = int32(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"SubmissionID\"")
|
return errors.Wrap(err, "decode field \"ResourceType\"")
|
||||||
|
}
|
||||||
|
case "ResourceID":
|
||||||
|
requiredBitSet[0] |= 1 << 5
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Int64()
|
||||||
|
s.ResourceID = int64(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"ResourceID\"")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
@@ -444,7 +671,7 @@ func (s *Script) Decode(d *jx.Decoder) error {
|
|||||||
// Validate required fields.
|
// Validate required fields.
|
||||||
var failures []validate.FieldError
|
var failures []validate.FieldError
|
||||||
for i, mask := range [1]uint8{
|
for i, mask := range [1]uint8{
|
||||||
0b00011111,
|
0b00111111,
|
||||||
} {
|
} {
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
@@ -508,17 +735,22 @@ func (s *ScriptCreate) encodeFields(e *jx.Encoder) {
|
|||||||
e.Str(s.Source)
|
e.Str(s.Source)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if s.SubmissionID.Set {
|
e.FieldStart("ResourceType")
|
||||||
e.FieldStart("SubmissionID")
|
e.Int32(s.ResourceType)
|
||||||
s.SubmissionID.Encode(e)
|
}
|
||||||
|
{
|
||||||
|
if s.ResourceID.Set {
|
||||||
|
e.FieldStart("ResourceID")
|
||||||
|
s.ResourceID.Encode(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfScriptCreate = [3]string{
|
var jsonFieldsNameOfScriptCreate = [4]string{
|
||||||
0: "Name",
|
0: "Name",
|
||||||
1: "Source",
|
1: "Source",
|
||||||
2: "SubmissionID",
|
2: "ResourceType",
|
||||||
|
3: "ResourceID",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes ScriptCreate from json.
|
// Decode decodes ScriptCreate from json.
|
||||||
@@ -554,15 +786,27 @@ func (s *ScriptCreate) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"Source\"")
|
return errors.Wrap(err, "decode field \"Source\"")
|
||||||
}
|
}
|
||||||
case "SubmissionID":
|
case "ResourceType":
|
||||||
|
requiredBitSet[0] |= 1 << 2
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
s.SubmissionID.Reset()
|
v, err := d.Int32()
|
||||||
if err := s.SubmissionID.Decode(d); err != nil {
|
s.ResourceType = int32(v)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"SubmissionID\"")
|
return errors.Wrap(err, "decode field \"ResourceType\"")
|
||||||
|
}
|
||||||
|
case "ResourceID":
|
||||||
|
if err := func() error {
|
||||||
|
s.ResourceID.Reset()
|
||||||
|
if err := s.ResourceID.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"ResourceID\"")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
@@ -574,7 +818,7 @@ func (s *ScriptCreate) Decode(d *jx.Decoder) error {
|
|||||||
// Validate required fields.
|
// Validate required fields.
|
||||||
var failures []validate.FieldError
|
var failures []validate.FieldError
|
||||||
for i, mask := range [1]uint8{
|
for i, mask := range [1]uint8{
|
||||||
0b00000011,
|
0b00000111,
|
||||||
} {
|
} {
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
@@ -1070,18 +1314,25 @@ func (s *ScriptUpdate) encodeFields(e *jx.Encoder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if s.SubmissionID.Set {
|
if s.ResourceType.Set {
|
||||||
e.FieldStart("SubmissionID")
|
e.FieldStart("ResourceType")
|
||||||
s.SubmissionID.Encode(e)
|
s.ResourceType.Encode(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if s.ResourceID.Set {
|
||||||
|
e.FieldStart("ResourceID")
|
||||||
|
s.ResourceID.Encode(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfScriptUpdate = [4]string{
|
var jsonFieldsNameOfScriptUpdate = [5]string{
|
||||||
0: "ID",
|
0: "ID",
|
||||||
1: "Name",
|
1: "Name",
|
||||||
2: "Source",
|
2: "Source",
|
||||||
3: "SubmissionID",
|
3: "ResourceType",
|
||||||
|
4: "ResourceID",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes ScriptUpdate from json.
|
// Decode decodes ScriptUpdate from json.
|
||||||
@@ -1125,15 +1376,25 @@ func (s *ScriptUpdate) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"Source\"")
|
return errors.Wrap(err, "decode field \"Source\"")
|
||||||
}
|
}
|
||||||
case "SubmissionID":
|
case "ResourceType":
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
s.SubmissionID.Reset()
|
s.ResourceType.Reset()
|
||||||
if err := s.SubmissionID.Decode(d); err != nil {
|
if err := s.ResourceType.Decode(d); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"SubmissionID\"")
|
return errors.Wrap(err, "decode field \"ResourceType\"")
|
||||||
|
}
|
||||||
|
case "ResourceID":
|
||||||
|
if err := func() error {
|
||||||
|
s.ResourceID.Reset()
|
||||||
|
if err := s.ResourceID.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"ResourceID\"")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
@@ -1241,19 +1502,19 @@ func (s *Submission) encodeFields(e *jx.Encoder) {
|
|||||||
e.Bool(s.Completed)
|
e.Bool(s.Completed)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
e.FieldStart("SubmissionType")
|
if s.UploadedAssetID.Set {
|
||||||
e.Int32(s.SubmissionType)
|
e.FieldStart("UploadedAssetID")
|
||||||
}
|
s.UploadedAssetID.Encode(e)
|
||||||
{
|
|
||||||
if s.TargetAssetID.Set {
|
|
||||||
e.FieldStart("TargetAssetID")
|
|
||||||
s.TargetAssetID.Encode(e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
e.FieldStart("StatusID")
|
e.FieldStart("StatusID")
|
||||||
e.Int32(s.StatusID)
|
e.Int32(s.StatusID)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("StatusMessage")
|
||||||
|
e.Str(s.StatusMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfSubmission = [13]string{
|
var jsonFieldsNameOfSubmission = [13]string{
|
||||||
@@ -1267,9 +1528,9 @@ var jsonFieldsNameOfSubmission = [13]string{
|
|||||||
7: "AssetID",
|
7: "AssetID",
|
||||||
8: "AssetVersion",
|
8: "AssetVersion",
|
||||||
9: "Completed",
|
9: "Completed",
|
||||||
10: "SubmissionType",
|
10: "UploadedAssetID",
|
||||||
11: "TargetAssetID",
|
11: "StatusID",
|
||||||
12: "StatusID",
|
12: "StatusMessage",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes Submission from json.
|
// Decode decodes Submission from json.
|
||||||
@@ -1401,30 +1662,18 @@ func (s *Submission) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"Completed\"")
|
return errors.Wrap(err, "decode field \"Completed\"")
|
||||||
}
|
}
|
||||||
case "SubmissionType":
|
case "UploadedAssetID":
|
||||||
requiredBitSet[1] |= 1 << 2
|
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
v, err := d.Int32()
|
s.UploadedAssetID.Reset()
|
||||||
s.SubmissionType = int32(v)
|
if err := s.UploadedAssetID.Decode(d); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"SubmissionType\"")
|
return errors.Wrap(err, "decode field \"UploadedAssetID\"")
|
||||||
}
|
|
||||||
case "TargetAssetID":
|
|
||||||
if err := func() error {
|
|
||||||
s.TargetAssetID.Reset()
|
|
||||||
if err := s.TargetAssetID.Decode(d); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"TargetAssetID\"")
|
|
||||||
}
|
}
|
||||||
case "StatusID":
|
case "StatusID":
|
||||||
requiredBitSet[1] |= 1 << 4
|
requiredBitSet[1] |= 1 << 3
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
v, err := d.Int32()
|
v, err := d.Int32()
|
||||||
s.StatusID = int32(v)
|
s.StatusID = int32(v)
|
||||||
@@ -1435,6 +1684,18 @@ func (s *Submission) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"StatusID\"")
|
return errors.Wrap(err, "decode field \"StatusID\"")
|
||||||
}
|
}
|
||||||
|
case "StatusMessage":
|
||||||
|
requiredBitSet[1] |= 1 << 4
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Str()
|
||||||
|
s.StatusMessage = string(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"StatusMessage\"")
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
}
|
}
|
||||||
@@ -1446,7 +1707,7 @@ func (s *Submission) Decode(d *jx.Decoder) error {
|
|||||||
var failures []validate.FieldError
|
var failures []validate.FieldError
|
||||||
for i, mask := range [2]uint8{
|
for i, mask := range [2]uint8{
|
||||||
0b11111111,
|
0b11111111,
|
||||||
0b00010111,
|
0b00011011,
|
||||||
} {
|
} {
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
@@ -1521,21 +1782,14 @@ func (s *SubmissionCreate) encodeFields(e *jx.Encoder) {
|
|||||||
e.FieldStart("AssetVersion")
|
e.FieldStart("AssetVersion")
|
||||||
e.Int64(s.AssetVersion)
|
e.Int64(s.AssetVersion)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
if s.TargetAssetID.Set {
|
|
||||||
e.FieldStart("TargetAssetID")
|
|
||||||
s.TargetAssetID.Encode(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfSubmissionCreate = [6]string{
|
var jsonFieldsNameOfSubmissionCreate = [5]string{
|
||||||
0: "DisplayName",
|
0: "DisplayName",
|
||||||
1: "Creator",
|
1: "Creator",
|
||||||
2: "GameID",
|
2: "GameID",
|
||||||
3: "AssetID",
|
3: "AssetID",
|
||||||
4: "AssetVersion",
|
4: "AssetVersion",
|
||||||
5: "TargetAssetID",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes SubmissionCreate from json.
|
// Decode decodes SubmissionCreate from json.
|
||||||
@@ -1607,16 +1861,6 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"AssetVersion\"")
|
return errors.Wrap(err, "decode field \"AssetVersion\"")
|
||||||
}
|
}
|
||||||
case "TargetAssetID":
|
|
||||||
if err := func() error {
|
|
||||||
s.TargetAssetID.Reset()
|
|
||||||
if err := s.TargetAssetID.Decode(d); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"TargetAssetID\"")
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
}
|
}
|
||||||
@@ -1672,3 +1916,133 @@ func (s *SubmissionCreate) UnmarshalJSON(data []byte) error {
|
|||||||
d := jx.DecodeBytes(data)
|
d := jx.DecodeBytes(data)
|
||||||
return s.Decode(d)
|
return s.Decode(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode implements json.Marshaler.
|
||||||
|
func (s *User) Encode(e *jx.Encoder) {
|
||||||
|
e.ObjStart()
|
||||||
|
s.encodeFields(e)
|
||||||
|
e.ObjEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeFields encodes fields.
|
||||||
|
func (s *User) encodeFields(e *jx.Encoder) {
|
||||||
|
{
|
||||||
|
e.FieldStart("UserID")
|
||||||
|
e.Int64(s.UserID)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("Username")
|
||||||
|
e.Str(s.Username)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("AvatarURL")
|
||||||
|
e.Str(s.AvatarURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonFieldsNameOfUser = [3]string{
|
||||||
|
0: "UserID",
|
||||||
|
1: "Username",
|
||||||
|
2: "AvatarURL",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decodes User from json.
|
||||||
|
func (s *User) Decode(d *jx.Decoder) error {
|
||||||
|
if s == nil {
|
||||||
|
return errors.New("invalid: unable to decode User to nil")
|
||||||
|
}
|
||||||
|
var requiredBitSet [1]uint8
|
||||||
|
|
||||||
|
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
|
||||||
|
switch string(k) {
|
||||||
|
case "UserID":
|
||||||
|
requiredBitSet[0] |= 1 << 0
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Int64()
|
||||||
|
s.UserID = int64(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"UserID\"")
|
||||||
|
}
|
||||||
|
case "Username":
|
||||||
|
requiredBitSet[0] |= 1 << 1
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Str()
|
||||||
|
s.Username = string(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"Username\"")
|
||||||
|
}
|
||||||
|
case "AvatarURL":
|
||||||
|
requiredBitSet[0] |= 1 << 2
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Str()
|
||||||
|
s.AvatarURL = string(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"AvatarURL\"")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return d.Skip()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return errors.Wrap(err, "decode User")
|
||||||
|
}
|
||||||
|
// Validate required fields.
|
||||||
|
var failures []validate.FieldError
|
||||||
|
for i, mask := range [1]uint8{
|
||||||
|
0b00000111,
|
||||||
|
} {
|
||||||
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
|
//
|
||||||
|
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
|
||||||
|
// Bits of fields which would be set are actually bits of missed fields.
|
||||||
|
missed := bits.OnesCount8(result)
|
||||||
|
for bitN := 0; bitN < missed; bitN++ {
|
||||||
|
bitIdx := bits.TrailingZeros8(result)
|
||||||
|
fieldIdx := i*8 + bitIdx
|
||||||
|
var name string
|
||||||
|
if fieldIdx < len(jsonFieldsNameOfUser) {
|
||||||
|
name = jsonFieldsNameOfUser[fieldIdx]
|
||||||
|
} else {
|
||||||
|
name = strconv.Itoa(fieldIdx)
|
||||||
|
}
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: name,
|
||||||
|
Error: validate.ErrFieldRequired,
|
||||||
|
})
|
||||||
|
// Reset bit.
|
||||||
|
result &^= 1 << bitIdx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements stdjson.Marshaler.
|
||||||
|
func (s *User) MarshalJSON() ([]byte, error) {
|
||||||
|
e := jx.Encoder{}
|
||||||
|
s.Encode(&e)
|
||||||
|
return e.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements stdjson.Unmarshaler.
|
||||||
|
func (s *User) UnmarshalJSON(data []byte) error {
|
||||||
|
d := jx.DecodeBytes(data)
|
||||||
|
return s.Decode(d)
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,12 +6,15 @@ package api
|
|||||||
type OperationName = string
|
type OperationName = string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
|
||||||
ActionSubmissionRejectOperation OperationName = "ActionSubmissionReject"
|
ActionSubmissionRejectOperation OperationName = "ActionSubmissionReject"
|
||||||
ActionSubmissionRequestChangesOperation OperationName = "ActionSubmissionRequestChanges"
|
ActionSubmissionRequestChangesOperation OperationName = "ActionSubmissionRequestChanges"
|
||||||
|
ActionSubmissionRetryValidateOperation OperationName = "ActionSubmissionRetryValidate"
|
||||||
ActionSubmissionRevokeOperation OperationName = "ActionSubmissionRevoke"
|
ActionSubmissionRevokeOperation OperationName = "ActionSubmissionRevoke"
|
||||||
ActionSubmissionSubmitOperation OperationName = "ActionSubmissionSubmit"
|
ActionSubmissionSubmitOperation OperationName = "ActionSubmissionSubmit"
|
||||||
ActionSubmissionTriggerUploadOperation OperationName = "ActionSubmissionTriggerUpload"
|
ActionSubmissionTriggerUploadOperation OperationName = "ActionSubmissionTriggerUpload"
|
||||||
ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate"
|
ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate"
|
||||||
|
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
||||||
CreateScriptOperation OperationName = "CreateScript"
|
CreateScriptOperation OperationName = "CreateScript"
|
||||||
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
||||||
CreateSubmissionOperation OperationName = "CreateSubmission"
|
CreateSubmissionOperation OperationName = "CreateSubmission"
|
||||||
@@ -23,6 +26,10 @@ const (
|
|||||||
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
||||||
ListScriptsOperation OperationName = "ListScripts"
|
ListScriptsOperation OperationName = "ListScripts"
|
||||||
ListSubmissionsOperation OperationName = "ListSubmissions"
|
ListSubmissionsOperation OperationName = "ListSubmissions"
|
||||||
|
ReleaseSubmissionsOperation OperationName = "ReleaseSubmissions"
|
||||||
|
SessionRolesOperation OperationName = "SessionRoles"
|
||||||
|
SessionUserOperation OperationName = "SessionUser"
|
||||||
|
SessionValidateOperation OperationName = "SessionValidate"
|
||||||
SetSubmissionCompletedOperation OperationName = "SetSubmissionCompleted"
|
SetSubmissionCompletedOperation OperationName = "SetSubmissionCompleted"
|
||||||
UpdateScriptOperation OperationName = "UpdateScript"
|
UpdateScriptOperation OperationName = "UpdateScript"
|
||||||
UpdateScriptPolicyOperation OperationName = "UpdateScriptPolicy"
|
UpdateScriptPolicyOperation OperationName = "UpdateScriptPolicy"
|
||||||
|
|||||||
@@ -15,6 +15,72 @@ import (
|
|||||||
"github.com/ogen-go/ogen/validate"
|
"github.com/ogen-go/ogen/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ActionSubmissionAcceptedParams is parameters of actionSubmissionAccepted operation.
|
||||||
|
type ActionSubmissionAcceptedParams struct {
|
||||||
|
// The unique identifier for a submission.
|
||||||
|
SubmissionID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackActionSubmissionAcceptedParams(packed middleware.Parameters) (params ActionSubmissionAcceptedParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.SubmissionID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeActionSubmissionAcceptedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionAcceptedParams, _ error) {
|
||||||
|
// Decode path: SubmissionID.
|
||||||
|
if err := func() error {
|
||||||
|
param := args[0]
|
||||||
|
if argsEscaped {
|
||||||
|
unescaped, err := url.PathUnescape(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "unescape path")
|
||||||
|
}
|
||||||
|
param = unescaped
|
||||||
|
}
|
||||||
|
if len(param) > 0 {
|
||||||
|
d := uri.NewPathDecoder(uri.PathDecoderConfig{
|
||||||
|
Param: "SubmissionID",
|
||||||
|
Value: param,
|
||||||
|
Style: uri.PathStyleSimple,
|
||||||
|
Explode: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := func() error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToInt64(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
params.SubmissionID = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return validate.ErrFieldRequired
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ActionSubmissionRejectParams is parameters of actionSubmissionReject operation.
|
// ActionSubmissionRejectParams is parameters of actionSubmissionReject operation.
|
||||||
type ActionSubmissionRejectParams struct {
|
type ActionSubmissionRejectParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
@@ -147,6 +213,72 @@ func decodeActionSubmissionRequestChangesParams(args [1]string, argsEscaped bool
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionRetryValidateParams is parameters of actionSubmissionRetryValidate operation.
|
||||||
|
type ActionSubmissionRetryValidateParams struct {
|
||||||
|
// The unique identifier for a submission.
|
||||||
|
SubmissionID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackActionSubmissionRetryValidateParams(packed middleware.Parameters) (params ActionSubmissionRetryValidateParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.SubmissionID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeActionSubmissionRetryValidateParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionRetryValidateParams, _ error) {
|
||||||
|
// Decode path: SubmissionID.
|
||||||
|
if err := func() error {
|
||||||
|
param := args[0]
|
||||||
|
if argsEscaped {
|
||||||
|
unescaped, err := url.PathUnescape(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "unescape path")
|
||||||
|
}
|
||||||
|
param = unescaped
|
||||||
|
}
|
||||||
|
if len(param) > 0 {
|
||||||
|
d := uri.NewPathDecoder(uri.PathDecoderConfig{
|
||||||
|
Param: "SubmissionID",
|
||||||
|
Value: param,
|
||||||
|
Style: uri.PathStyleSimple,
|
||||||
|
Explode: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := func() error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToInt64(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
params.SubmissionID = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return validate.ErrFieldRequired
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ActionSubmissionRevokeParams is parameters of actionSubmissionRevoke operation.
|
// ActionSubmissionRevokeParams is parameters of actionSubmissionRevoke operation.
|
||||||
type ActionSubmissionRevokeParams struct {
|
type ActionSubmissionRevokeParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
@@ -411,6 +543,72 @@ func decodeActionSubmissionTriggerValidateParams(args [1]string, argsEscaped boo
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionValidatedParams is parameters of actionSubmissionValidated operation.
|
||||||
|
type ActionSubmissionValidatedParams struct {
|
||||||
|
// The unique identifier for a submission.
|
||||||
|
SubmissionID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackActionSubmissionValidatedParams(packed middleware.Parameters) (params ActionSubmissionValidatedParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.SubmissionID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeActionSubmissionValidatedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionValidatedParams, _ error) {
|
||||||
|
// Decode path: SubmissionID.
|
||||||
|
if err := func() error {
|
||||||
|
param := args[0]
|
||||||
|
if argsEscaped {
|
||||||
|
unescaped, err := url.PathUnescape(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "unescape path")
|
||||||
|
}
|
||||||
|
param = unescaped
|
||||||
|
}
|
||||||
|
if len(param) > 0 {
|
||||||
|
d := uri.NewPathDecoder(uri.PathDecoderConfig{
|
||||||
|
Param: "SubmissionID",
|
||||||
|
Value: param,
|
||||||
|
Style: uri.PathStyleSimple,
|
||||||
|
Explode: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := func() error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToInt64(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
params.SubmissionID = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return validate.ErrFieldRequired
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteScriptParams is parameters of deleteScript operation.
|
// DeleteScriptParams is parameters of deleteScript operation.
|
||||||
type DeleteScriptParams struct {
|
type DeleteScriptParams struct {
|
||||||
// The unique identifier for a script.
|
// The unique identifier for a script.
|
||||||
@@ -840,7 +1038,7 @@ func decodeListScriptPolicyParams(args [0]string, argsEscaped bool, r *http.Requ
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -893,7 +1091,7 @@ func decodeListScriptPolicyParams(args [0]string, argsEscaped bool, r *http.Requ
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -1161,7 +1359,7 @@ func decodeListScriptsParams(args [0]string, argsEscaped bool, r *http.Request)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -1214,7 +1412,7 @@ func decodeListScriptsParams(args [0]string, argsEscaped bool, r *http.Request)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -1467,6 +1665,7 @@ type ListSubmissionsParams struct {
|
|||||||
DisplayName OptString
|
DisplayName OptString
|
||||||
Creator OptString
|
Creator OptString
|
||||||
GameID OptInt32
|
GameID OptInt32
|
||||||
|
Sort OptInt32
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackListSubmissionsParams(packed middleware.Parameters) (params ListSubmissionsParams) {
|
func unpackListSubmissionsParams(packed middleware.Parameters) (params ListSubmissionsParams) {
|
||||||
@@ -1511,6 +1710,15 @@ func unpackListSubmissionsParams(packed middleware.Parameters) (params ListSubmi
|
|||||||
params.GameID = v.(OptInt32)
|
params.GameID = v.(OptInt32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "Sort",
|
||||||
|
In: "query",
|
||||||
|
}
|
||||||
|
if v, ok := packed[key]; ok {
|
||||||
|
params.Sort = v.(OptInt32)
|
||||||
|
}
|
||||||
|
}
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1559,7 +1767,7 @@ func decodeListSubmissionsParams(args [0]string, argsEscaped bool, r *http.Reque
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -1612,7 +1820,7 @@ func decodeListSubmissionsParams(args [0]string, argsEscaped bool, r *http.Reque
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -1791,6 +1999,47 @@ func decodeListSubmissionsParams(args [0]string, argsEscaped bool, r *http.Reque
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Decode query: Sort.
|
||||||
|
if err := func() error {
|
||||||
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
|
Name: "Sort",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.HasParam(cfg); err == nil {
|
||||||
|
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
||||||
|
var paramsDotSortVal int32
|
||||||
|
if err := func() error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToInt32(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
paramsDotSortVal = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params.Sort.SetTo(paramsDotSortVal)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "Sort",
|
||||||
|
In: "query",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2098,7 +2347,7 @@ func decodeUpdateSubmissionModelParams(args [1]string, argsEscaped bool, r *http
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -2134,7 +2383,7 @@ func decodeUpdateSubmissionModelParams(args [1]string, argsEscaped bool, r *http
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
|
|||||||
@@ -220,6 +220,93 @@ func (s *Server) decodeCreateSubmissionRequest(r *http.Request) (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) decodeReleaseSubmissionsRequest(r *http.Request) (
|
||||||
|
req []ReleaseInfo,
|
||||||
|
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 = multierr.Append(merr, c())
|
||||||
|
}
|
||||||
|
return merr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if rerr != nil {
|
||||||
|
rerr = multierr.Append(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 []ReleaseInfo
|
||||||
|
if err := func() error {
|
||||||
|
request = make([]ReleaseInfo, 0)
|
||||||
|
if err := d.Arr(func(d *jx.Decoder) error {
|
||||||
|
var elem ReleaseInfo
|
||||||
|
if err := elem.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
request = append(request, elem)
|
||||||
|
return nil
|
||||||
|
}); 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 request == nil {
|
||||||
|
return errors.New("nil is invalid value")
|
||||||
|
}
|
||||||
|
if err := (validate.Array{
|
||||||
|
MinLength: 1,
|
||||||
|
MinLengthSet: true,
|
||||||
|
MaxLength: 255,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
}).ValidateLength(len(request)); err != nil {
|
||||||
|
return errors.Wrap(err, "array")
|
||||||
|
}
|
||||||
|
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) decodeUpdateScriptRequest(r *http.Request) (
|
func (s *Server) decodeUpdateScriptRequest(r *http.Request) (
|
||||||
req *ScriptUpdate,
|
req *ScriptUpdate,
|
||||||
close func() error,
|
close func() error,
|
||||||
|
|||||||
@@ -53,6 +53,24 @@ func encodeCreateSubmissionRequest(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeReleaseSubmissionsRequest(
|
||||||
|
req []ReleaseInfo,
|
||||||
|
r *http.Request,
|
||||||
|
) error {
|
||||||
|
const contentType = "application/json"
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
{
|
||||||
|
e.ArrStart()
|
||||||
|
for _, elem := range req {
|
||||||
|
elem.Encode(e)
|
||||||
|
}
|
||||||
|
e.ArrEnd()
|
||||||
|
}
|
||||||
|
encoded := e.Bytes()
|
||||||
|
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeUpdateScriptRequest(
|
func encodeUpdateScriptRequest(
|
||||||
req *ScriptUpdate,
|
req *ScriptUpdate,
|
||||||
r *http.Request,
|
r *http.Request,
|
||||||
|
|||||||
@@ -15,6 +15,57 @@ import (
|
|||||||
"github.com/ogen-go/ogen/validate"
|
"github.com/ogen-go/ogen/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func decodeActionSubmissionAcceptedResponse(resp *http.Response) (res *ActionSubmissionAcceptedNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &ActionSubmissionAcceptedNoContent{}, nil
|
||||||
|
}
|
||||||
|
// Convenient error response.
|
||||||
|
defRes, err := func() (res *ErrorStatusCode, err error) {
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response Error
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
return &ErrorStatusCode{
|
||||||
|
StatusCode: resp.StatusCode,
|
||||||
|
Response: response,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return res, errors.Wrap(defRes, "error")
|
||||||
|
}
|
||||||
|
|
||||||
func decodeActionSubmissionRejectResponse(resp *http.Response) (res *ActionSubmissionRejectNoContent, _ error) {
|
func decodeActionSubmissionRejectResponse(resp *http.Response) (res *ActionSubmissionRejectNoContent, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 204:
|
case 204:
|
||||||
@@ -117,6 +168,57 @@ func decodeActionSubmissionRequestChangesResponse(resp *http.Response) (res *Act
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeActionSubmissionRetryValidateResponse(resp *http.Response) (res *ActionSubmissionRetryValidateNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &ActionSubmissionRetryValidateNoContent{}, nil
|
||||||
|
}
|
||||||
|
// Convenient error response.
|
||||||
|
defRes, err := func() (res *ErrorStatusCode, err error) {
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response Error
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
return &ErrorStatusCode{
|
||||||
|
StatusCode: resp.StatusCode,
|
||||||
|
Response: response,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return res, errors.Wrap(defRes, "error")
|
||||||
|
}
|
||||||
|
|
||||||
func decodeActionSubmissionRevokeResponse(resp *http.Response) (res *ActionSubmissionRevokeNoContent, _ error) {
|
func decodeActionSubmissionRevokeResponse(resp *http.Response) (res *ActionSubmissionRevokeNoContent, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 204:
|
case 204:
|
||||||
@@ -321,6 +423,57 @@ func decodeActionSubmissionTriggerValidateResponse(resp *http.Response) (res *Ac
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeActionSubmissionValidatedResponse(resp *http.Response) (res *ActionSubmissionValidatedNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &ActionSubmissionValidatedNoContent{}, nil
|
||||||
|
}
|
||||||
|
// Convenient error response.
|
||||||
|
defRes, err := func() (res *ErrorStatusCode, err error) {
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response Error
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
return &ErrorStatusCode{
|
||||||
|
StatusCode: resp.StatusCode,
|
||||||
|
Response: response,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return res, errors.Wrap(defRes, "error")
|
||||||
|
}
|
||||||
|
|
||||||
func decodeCreateScriptResponse(resp *http.Response) (res *ID, _ error) {
|
func decodeCreateScriptResponse(resp *http.Response) (res *ID, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 201:
|
case 201:
|
||||||
@@ -1299,6 +1452,317 @@ func decodeListSubmissionsResponse(resp *http.Response) (res []Submission, _ err
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeReleaseSubmissionsResponse(resp *http.Response) (res *ReleaseSubmissionsCreated, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 201:
|
||||||
|
// Code 201.
|
||||||
|
return &ReleaseSubmissionsCreated{}, nil
|
||||||
|
}
|
||||||
|
// Convenient error response.
|
||||||
|
defRes, err := func() (res *ErrorStatusCode, err error) {
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response Error
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
return &ErrorStatusCode{
|
||||||
|
StatusCode: resp.StatusCode,
|
||||||
|
Response: response,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return res, errors.Wrap(defRes, "error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSessionRolesResponse(resp *http.Response) (res *Roles, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 200:
|
||||||
|
// Code 200.
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response Roles
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
return &response, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Convenient error response.
|
||||||
|
defRes, err := func() (res *ErrorStatusCode, err error) {
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response Error
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
return &ErrorStatusCode{
|
||||||
|
StatusCode: resp.StatusCode,
|
||||||
|
Response: response,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return res, errors.Wrap(defRes, "error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSessionUserResponse(resp *http.Response) (res *User, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 200:
|
||||||
|
// Code 200.
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response User
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
// Validate response.
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return res, errors.Wrap(err, "validate")
|
||||||
|
}
|
||||||
|
return &response, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Convenient error response.
|
||||||
|
defRes, err := func() (res *ErrorStatusCode, err error) {
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response Error
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
return &ErrorStatusCode{
|
||||||
|
StatusCode: resp.StatusCode,
|
||||||
|
Response: response,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return res, errors.Wrap(defRes, "error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSessionValidateResponse(resp *http.Response) (res bool, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 200:
|
||||||
|
// Code 200.
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response bool
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Bool()
|
||||||
|
response = bool(v)
|
||||||
|
if 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 res, err
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Convenient error response.
|
||||||
|
defRes, err := func() (res *ErrorStatusCode, err error) {
|
||||||
|
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
buf, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var response Error
|
||||||
|
if err := func() error {
|
||||||
|
if err := response.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 res, err
|
||||||
|
}
|
||||||
|
return &ErrorStatusCode{
|
||||||
|
StatusCode: resp.StatusCode,
|
||||||
|
Response: response,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return res, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return res, errors.Wrap(defRes, "error")
|
||||||
|
}
|
||||||
|
|
||||||
func decodeSetSubmissionCompletedResponse(resp *http.Response) (res *SetSubmissionCompletedNoContent, _ error) {
|
func decodeSetSubmissionCompletedResponse(resp *http.Response) (res *SetSubmissionCompletedNoContent, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 204:
|
case 204:
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ import (
|
|||||||
ht "github.com/ogen-go/ogen/http"
|
ht "github.com/ogen-go/ogen/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func encodeActionSubmissionAcceptedResponse(response *ActionSubmissionAcceptedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeActionSubmissionRejectResponse(response *ActionSubmissionRejectNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionSubmissionRejectResponse(response *ActionSubmissionRejectNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.WriteHeader(204)
|
w.WriteHeader(204)
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
@@ -27,6 +34,13 @@ func encodeActionSubmissionRequestChangesResponse(response *ActionSubmissionRequ
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeActionSubmissionRetryValidateResponse(response *ActionSubmissionRetryValidateNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeActionSubmissionRevokeResponse(response *ActionSubmissionRevokeNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionSubmissionRevokeResponse(response *ActionSubmissionRevokeNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.WriteHeader(204)
|
w.WriteHeader(204)
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
@@ -55,6 +69,13 @@ func encodeActionSubmissionTriggerValidateResponse(response *ActionSubmissionTri
|
|||||||
return nil
|
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 encodeCreateScriptResponse(response *ID, w http.ResponseWriter, span trace.Span) error {
|
func encodeCreateScriptResponse(response *ID, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
w.WriteHeader(201)
|
w.WriteHeader(201)
|
||||||
@@ -207,6 +228,55 @@ func encodeListSubmissionsResponse(response []Submission, w http.ResponseWriter,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeReleaseSubmissionsResponse(response *ReleaseSubmissionsCreated, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(201)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(201))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeSessionRolesResponse(response *Roles, 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 encodeSessionUserResponse(response *User, 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 encodeSessionValidateResponse(response bool, 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.Bool(response)
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeSetSubmissionCompletedResponse(response *SetSubmissionCompletedNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeSetSubmissionCompletedResponse(response *SetSubmissionCompletedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.WriteHeader(204)
|
w.WriteHeader(204)
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,18 +4,25 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *ErrorStatusCode) Error() string {
|
func (s *ErrorStatusCode) Error() string {
|
||||||
return fmt.Sprintf("code %d: %+v", s.StatusCode, s.Response)
|
return fmt.Sprintf("code %d: %+v", s.StatusCode, s.Response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionAcceptedNoContent is response for ActionSubmissionAccepted operation.
|
||||||
|
type ActionSubmissionAcceptedNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionRejectNoContent is response for ActionSubmissionReject operation.
|
// ActionSubmissionRejectNoContent is response for ActionSubmissionReject operation.
|
||||||
type ActionSubmissionRejectNoContent struct{}
|
type ActionSubmissionRejectNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionRequestChangesNoContent is response for ActionSubmissionRequestChanges operation.
|
// ActionSubmissionRequestChangesNoContent is response for ActionSubmissionRequestChanges operation.
|
||||||
type ActionSubmissionRequestChangesNoContent struct{}
|
type ActionSubmissionRequestChangesNoContent struct{}
|
||||||
|
|
||||||
|
// ActionSubmissionRetryValidateNoContent is response for ActionSubmissionRetryValidate operation.
|
||||||
|
type ActionSubmissionRetryValidateNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionRevokeNoContent is response for ActionSubmissionRevoke operation.
|
// ActionSubmissionRevokeNoContent is response for ActionSubmissionRevoke operation.
|
||||||
type ActionSubmissionRevokeNoContent struct{}
|
type ActionSubmissionRevokeNoContent struct{}
|
||||||
|
|
||||||
@@ -28,6 +35,9 @@ type ActionSubmissionTriggerUploadNoContent struct{}
|
|||||||
// ActionSubmissionTriggerValidateNoContent is response for ActionSubmissionTriggerValidate operation.
|
// ActionSubmissionTriggerValidateNoContent is response for ActionSubmissionTriggerValidate operation.
|
||||||
type ActionSubmissionTriggerValidateNoContent struct{}
|
type ActionSubmissionTriggerValidateNoContent struct{}
|
||||||
|
|
||||||
|
// ActionSubmissionValidatedNoContent is response for ActionSubmissionValidated operation.
|
||||||
|
type ActionSubmissionValidatedNoContent struct{}
|
||||||
|
|
||||||
type CookieAuth struct {
|
type CookieAuth struct {
|
||||||
APIKey string
|
APIKey string
|
||||||
}
|
}
|
||||||
@@ -254,13 +264,58 @@ func (o OptString) Or(d string) string {
|
|||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/ReleaseInfo
|
||||||
|
type ReleaseInfo struct {
|
||||||
|
SubmissionID int64 `json:"SubmissionID"`
|
||||||
|
Date time.Time `json:"Date"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSubmissionID returns the value of SubmissionID.
|
||||||
|
func (s *ReleaseInfo) GetSubmissionID() int64 {
|
||||||
|
return s.SubmissionID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDate returns the value of Date.
|
||||||
|
func (s *ReleaseInfo) GetDate() time.Time {
|
||||||
|
return s.Date
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSubmissionID sets the value of SubmissionID.
|
||||||
|
func (s *ReleaseInfo) SetSubmissionID(val int64) {
|
||||||
|
s.SubmissionID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDate sets the value of Date.
|
||||||
|
func (s *ReleaseInfo) SetDate(val time.Time) {
|
||||||
|
s.Date = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseSubmissionsCreated is response for ReleaseSubmissions operation.
|
||||||
|
type ReleaseSubmissionsCreated struct{}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/Roles
|
||||||
|
type Roles struct {
|
||||||
|
Roles int32 `json:"Roles"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRoles returns the value of Roles.
|
||||||
|
func (s *Roles) GetRoles() int32 {
|
||||||
|
return s.Roles
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRoles sets the value of Roles.
|
||||||
|
func (s *Roles) SetRoles(val int32) {
|
||||||
|
s.Roles = val
|
||||||
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/Script
|
// Ref: #/components/schemas/Script
|
||||||
type Script struct {
|
type Script struct {
|
||||||
ID int64 `json:"ID"`
|
ID int64 `json:"ID"`
|
||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
Hash string `json:"Hash"`
|
Hash string `json:"Hash"`
|
||||||
Source string `json:"Source"`
|
Source string `json:"Source"`
|
||||||
SubmissionID int64 `json:"SubmissionID"`
|
ResourceType int32 `json:"ResourceType"`
|
||||||
|
ResourceID int64 `json:"ResourceID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID returns the value of ID.
|
// GetID returns the value of ID.
|
||||||
@@ -283,9 +338,14 @@ func (s *Script) GetSource() string {
|
|||||||
return s.Source
|
return s.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubmissionID returns the value of SubmissionID.
|
// GetResourceType returns the value of ResourceType.
|
||||||
func (s *Script) GetSubmissionID() int64 {
|
func (s *Script) GetResourceType() int32 {
|
||||||
return s.SubmissionID
|
return s.ResourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceID returns the value of ResourceID.
|
||||||
|
func (s *Script) GetResourceID() int64 {
|
||||||
|
return s.ResourceID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetID sets the value of ID.
|
// SetID sets the value of ID.
|
||||||
@@ -308,16 +368,22 @@ func (s *Script) SetSource(val string) {
|
|||||||
s.Source = val
|
s.Source = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSubmissionID sets the value of SubmissionID.
|
// SetResourceType sets the value of ResourceType.
|
||||||
func (s *Script) SetSubmissionID(val int64) {
|
func (s *Script) SetResourceType(val int32) {
|
||||||
s.SubmissionID = val
|
s.ResourceType = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceID sets the value of ResourceID.
|
||||||
|
func (s *Script) SetResourceID(val int64) {
|
||||||
|
s.ResourceID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/ScriptCreate
|
// Ref: #/components/schemas/ScriptCreate
|
||||||
type ScriptCreate struct {
|
type ScriptCreate struct {
|
||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
Source string `json:"Source"`
|
Source string `json:"Source"`
|
||||||
SubmissionID OptInt64 `json:"SubmissionID"`
|
ResourceType int32 `json:"ResourceType"`
|
||||||
|
ResourceID OptInt64 `json:"ResourceID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetName returns the value of Name.
|
// GetName returns the value of Name.
|
||||||
@@ -330,9 +396,14 @@ func (s *ScriptCreate) GetSource() string {
|
|||||||
return s.Source
|
return s.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubmissionID returns the value of SubmissionID.
|
// GetResourceType returns the value of ResourceType.
|
||||||
func (s *ScriptCreate) GetSubmissionID() OptInt64 {
|
func (s *ScriptCreate) GetResourceType() int32 {
|
||||||
return s.SubmissionID
|
return s.ResourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceID returns the value of ResourceID.
|
||||||
|
func (s *ScriptCreate) GetResourceID() OptInt64 {
|
||||||
|
return s.ResourceID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetName sets the value of Name.
|
// SetName sets the value of Name.
|
||||||
@@ -345,9 +416,14 @@ func (s *ScriptCreate) SetSource(val string) {
|
|||||||
s.Source = val
|
s.Source = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSubmissionID sets the value of SubmissionID.
|
// SetResourceType sets the value of ResourceType.
|
||||||
func (s *ScriptCreate) SetSubmissionID(val OptInt64) {
|
func (s *ScriptCreate) SetResourceType(val int32) {
|
||||||
s.SubmissionID = val
|
s.ResourceType = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceID sets the value of ResourceID.
|
||||||
|
func (s *ScriptCreate) SetResourceID(val OptInt64) {
|
||||||
|
s.ResourceID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/ScriptPolicy
|
// Ref: #/components/schemas/ScriptPolicy
|
||||||
@@ -488,7 +564,8 @@ type ScriptUpdate struct {
|
|||||||
ID int64 `json:"ID"`
|
ID int64 `json:"ID"`
|
||||||
Name OptString `json:"Name"`
|
Name OptString `json:"Name"`
|
||||||
Source OptString `json:"Source"`
|
Source OptString `json:"Source"`
|
||||||
SubmissionID OptInt64 `json:"SubmissionID"`
|
ResourceType OptInt32 `json:"ResourceType"`
|
||||||
|
ResourceID OptInt64 `json:"ResourceID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID returns the value of ID.
|
// GetID returns the value of ID.
|
||||||
@@ -506,9 +583,14 @@ func (s *ScriptUpdate) GetSource() OptString {
|
|||||||
return s.Source
|
return s.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubmissionID returns the value of SubmissionID.
|
// GetResourceType returns the value of ResourceType.
|
||||||
func (s *ScriptUpdate) GetSubmissionID() OptInt64 {
|
func (s *ScriptUpdate) GetResourceType() OptInt32 {
|
||||||
return s.SubmissionID
|
return s.ResourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceID returns the value of ResourceID.
|
||||||
|
func (s *ScriptUpdate) GetResourceID() OptInt64 {
|
||||||
|
return s.ResourceID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetID sets the value of ID.
|
// SetID sets the value of ID.
|
||||||
@@ -526,9 +608,14 @@ func (s *ScriptUpdate) SetSource(val OptString) {
|
|||||||
s.Source = val
|
s.Source = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSubmissionID sets the value of SubmissionID.
|
// SetResourceType sets the value of ResourceType.
|
||||||
func (s *ScriptUpdate) SetSubmissionID(val OptInt64) {
|
func (s *ScriptUpdate) SetResourceType(val OptInt32) {
|
||||||
s.SubmissionID = val
|
s.ResourceType = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceID sets the value of ResourceID.
|
||||||
|
func (s *ScriptUpdate) SetResourceID(val OptInt64) {
|
||||||
|
s.ResourceID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSubmissionCompletedNoContent is response for SetSubmissionCompleted operation.
|
// SetSubmissionCompletedNoContent is response for SetSubmissionCompleted operation.
|
||||||
@@ -536,19 +623,19 @@ type SetSubmissionCompletedNoContent struct{}
|
|||||||
|
|
||||||
// Ref: #/components/schemas/Submission
|
// Ref: #/components/schemas/Submission
|
||||||
type Submission struct {
|
type Submission struct {
|
||||||
ID int64 `json:"ID"`
|
ID int64 `json:"ID"`
|
||||||
DisplayName string `json:"DisplayName"`
|
DisplayName string `json:"DisplayName"`
|
||||||
Creator string `json:"Creator"`
|
Creator string `json:"Creator"`
|
||||||
GameID int32 `json:"GameID"`
|
GameID int32 `json:"GameID"`
|
||||||
CreatedAt int64 `json:"CreatedAt"`
|
CreatedAt int64 `json:"CreatedAt"`
|
||||||
UpdatedAt int64 `json:"UpdatedAt"`
|
UpdatedAt int64 `json:"UpdatedAt"`
|
||||||
Submitter int64 `json:"Submitter"`
|
Submitter int64 `json:"Submitter"`
|
||||||
AssetID int64 `json:"AssetID"`
|
AssetID int64 `json:"AssetID"`
|
||||||
AssetVersion int64 `json:"AssetVersion"`
|
AssetVersion int64 `json:"AssetVersion"`
|
||||||
Completed bool `json:"Completed"`
|
Completed bool `json:"Completed"`
|
||||||
SubmissionType int32 `json:"SubmissionType"`
|
UploadedAssetID OptInt64 `json:"UploadedAssetID"`
|
||||||
TargetAssetID OptInt64 `json:"TargetAssetID"`
|
StatusID int32 `json:"StatusID"`
|
||||||
StatusID int32 `json:"StatusID"`
|
StatusMessage string `json:"StatusMessage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID returns the value of ID.
|
// GetID returns the value of ID.
|
||||||
@@ -601,14 +688,9 @@ func (s *Submission) GetCompleted() bool {
|
|||||||
return s.Completed
|
return s.Completed
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubmissionType returns the value of SubmissionType.
|
// GetUploadedAssetID returns the value of UploadedAssetID.
|
||||||
func (s *Submission) GetSubmissionType() int32 {
|
func (s *Submission) GetUploadedAssetID() OptInt64 {
|
||||||
return s.SubmissionType
|
return s.UploadedAssetID
|
||||||
}
|
|
||||||
|
|
||||||
// GetTargetAssetID returns the value of TargetAssetID.
|
|
||||||
func (s *Submission) GetTargetAssetID() OptInt64 {
|
|
||||||
return s.TargetAssetID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStatusID returns the value of StatusID.
|
// GetStatusID returns the value of StatusID.
|
||||||
@@ -616,6 +698,11 @@ func (s *Submission) GetStatusID() int32 {
|
|||||||
return s.StatusID
|
return s.StatusID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetStatusMessage returns the value of StatusMessage.
|
||||||
|
func (s *Submission) GetStatusMessage() string {
|
||||||
|
return s.StatusMessage
|
||||||
|
}
|
||||||
|
|
||||||
// SetID sets the value of ID.
|
// SetID sets the value of ID.
|
||||||
func (s *Submission) SetID(val int64) {
|
func (s *Submission) SetID(val int64) {
|
||||||
s.ID = val
|
s.ID = val
|
||||||
@@ -666,14 +753,9 @@ func (s *Submission) SetCompleted(val bool) {
|
|||||||
s.Completed = val
|
s.Completed = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSubmissionType sets the value of SubmissionType.
|
// SetUploadedAssetID sets the value of UploadedAssetID.
|
||||||
func (s *Submission) SetSubmissionType(val int32) {
|
func (s *Submission) SetUploadedAssetID(val OptInt64) {
|
||||||
s.SubmissionType = val
|
s.UploadedAssetID = val
|
||||||
}
|
|
||||||
|
|
||||||
// SetTargetAssetID sets the value of TargetAssetID.
|
|
||||||
func (s *Submission) SetTargetAssetID(val OptInt64) {
|
|
||||||
s.TargetAssetID = val
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStatusID sets the value of StatusID.
|
// SetStatusID sets the value of StatusID.
|
||||||
@@ -681,14 +763,18 @@ func (s *Submission) SetStatusID(val int32) {
|
|||||||
s.StatusID = val
|
s.StatusID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetStatusMessage sets the value of StatusMessage.
|
||||||
|
func (s *Submission) SetStatusMessage(val string) {
|
||||||
|
s.StatusMessage = val
|
||||||
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/SubmissionCreate
|
// Ref: #/components/schemas/SubmissionCreate
|
||||||
type SubmissionCreate struct {
|
type SubmissionCreate struct {
|
||||||
DisplayName string `json:"DisplayName"`
|
DisplayName string `json:"DisplayName"`
|
||||||
Creator string `json:"Creator"`
|
Creator string `json:"Creator"`
|
||||||
GameID int32 `json:"GameID"`
|
GameID int32 `json:"GameID"`
|
||||||
AssetID int64 `json:"AssetID"`
|
AssetID int64 `json:"AssetID"`
|
||||||
AssetVersion int64 `json:"AssetVersion"`
|
AssetVersion int64 `json:"AssetVersion"`
|
||||||
TargetAssetID OptInt64 `json:"TargetAssetID"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDisplayName returns the value of DisplayName.
|
// GetDisplayName returns the value of DisplayName.
|
||||||
@@ -716,11 +802,6 @@ func (s *SubmissionCreate) GetAssetVersion() int64 {
|
|||||||
return s.AssetVersion
|
return s.AssetVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTargetAssetID returns the value of TargetAssetID.
|
|
||||||
func (s *SubmissionCreate) GetTargetAssetID() OptInt64 {
|
|
||||||
return s.TargetAssetID
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDisplayName sets the value of DisplayName.
|
// SetDisplayName sets the value of DisplayName.
|
||||||
func (s *SubmissionCreate) SetDisplayName(val string) {
|
func (s *SubmissionCreate) SetDisplayName(val string) {
|
||||||
s.DisplayName = val
|
s.DisplayName = val
|
||||||
@@ -746,11 +827,6 @@ func (s *SubmissionCreate) SetAssetVersion(val int64) {
|
|||||||
s.AssetVersion = val
|
s.AssetVersion = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTargetAssetID sets the value of TargetAssetID.
|
|
||||||
func (s *SubmissionCreate) SetTargetAssetID(val OptInt64) {
|
|
||||||
s.TargetAssetID = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateScriptNoContent is response for UpdateScript operation.
|
// UpdateScriptNoContent is response for UpdateScript operation.
|
||||||
type UpdateScriptNoContent struct{}
|
type UpdateScriptNoContent struct{}
|
||||||
|
|
||||||
@@ -759,3 +835,40 @@ type UpdateScriptPolicyNoContent struct{}
|
|||||||
|
|
||||||
// UpdateSubmissionModelNoContent is response for UpdateSubmissionModel operation.
|
// UpdateSubmissionModelNoContent is response for UpdateSubmissionModel operation.
|
||||||
type UpdateSubmissionModelNoContent struct{}
|
type UpdateSubmissionModelNoContent struct{}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/User
|
||||||
|
type User struct {
|
||||||
|
UserID int64 `json:"UserID"`
|
||||||
|
Username string `json:"Username"`
|
||||||
|
AvatarURL string `json:"AvatarURL"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserID returns the value of UserID.
|
||||||
|
func (s *User) GetUserID() int64 {
|
||||||
|
return s.UserID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUsername returns the value of Username.
|
||||||
|
func (s *User) GetUsername() string {
|
||||||
|
return s.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAvatarURL returns the value of AvatarURL.
|
||||||
|
func (s *User) GetAvatarURL() string {
|
||||||
|
return s.AvatarURL
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserID sets the value of UserID.
|
||||||
|
func (s *User) SetUserID(val int64) {
|
||||||
|
s.UserID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUsername sets the value of Username.
|
||||||
|
func (s *User) SetUsername(val string) {
|
||||||
|
s.Username = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAvatarURL sets the value of AvatarURL.
|
||||||
|
func (s *User) SetAvatarURL(val string) {
|
||||||
|
s.AvatarURL = val
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ import (
|
|||||||
|
|
||||||
// Handler handles operations described by OpenAPI v3 specification.
|
// Handler handles operations described by OpenAPI v3 specification.
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer manually resets validating softlock and changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reset-validating
|
||||||
|
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
||||||
// ActionSubmissionReject implements actionSubmissionReject operation.
|
// ActionSubmissionReject implements actionSubmissionReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -20,6 +26,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/request-changes
|
// POST /submissions/{SubmissionID}/status/request-changes
|
||||||
ActionSubmissionRequestChanges(ctx context.Context, params ActionSubmissionRequestChangesParams) error
|
ActionSubmissionRequestChanges(ctx context.Context, params ActionSubmissionRequestChangesParams) error
|
||||||
|
// ActionSubmissionRetryValidate implements actionSubmissionRetryValidate operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/retry-validate
|
||||||
|
ActionSubmissionRetryValidate(ctx context.Context, params ActionSubmissionRetryValidateParams) error
|
||||||
// ActionSubmissionRevoke implements actionSubmissionRevoke operation.
|
// ActionSubmissionRevoke implements actionSubmissionRevoke operation.
|
||||||
//
|
//
|
||||||
// Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction.
|
// Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction.
|
||||||
@@ -40,10 +52,16 @@ type Handler interface {
|
|||||||
ActionSubmissionTriggerUpload(ctx context.Context, params ActionSubmissionTriggerUploadParams) error
|
ActionSubmissionTriggerUpload(ctx context.Context, params ActionSubmissionTriggerUploadParams) error
|
||||||
// ActionSubmissionTriggerValidate implements actionSubmissionTriggerValidate operation.
|
// ActionSubmissionTriggerValidate implements actionSubmissionTriggerValidate operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating.
|
// Role Reviewer triggers validation and changes status from Submitted -> Validating.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/trigger-validate
|
// POST /submissions/{SubmissionID}/status/trigger-validate
|
||||||
ActionSubmissionTriggerValidate(ctx context.Context, params ActionSubmissionTriggerValidateParams) error
|
ActionSubmissionTriggerValidate(ctx context.Context, params ActionSubmissionTriggerValidateParams) error
|
||||||
|
// ActionSubmissionValidated implements actionSubmissionValidated operation.
|
||||||
|
//
|
||||||
|
// Role Admin manually resets uploading softlock and changes status from Uploading -> Validated.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reset-uploading
|
||||||
|
ActionSubmissionValidated(ctx context.Context, params ActionSubmissionValidatedParams) error
|
||||||
// CreateScript implements createScript operation.
|
// CreateScript implements createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -110,9 +128,33 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// GET /submissions
|
// GET /submissions
|
||||||
ListSubmissions(ctx context.Context, params ListSubmissionsParams) ([]Submission, error)
|
ListSubmissions(ctx context.Context, params ListSubmissionsParams) ([]Submission, error)
|
||||||
|
// ReleaseSubmissions implements releaseSubmissions operation.
|
||||||
|
//
|
||||||
|
// Release a set of uploaded maps.
|
||||||
|
//
|
||||||
|
// POST /release-submissions
|
||||||
|
ReleaseSubmissions(ctx context.Context, req []ReleaseInfo) error
|
||||||
|
// SessionRoles implements sessionRoles operation.
|
||||||
|
//
|
||||||
|
// Get list of roles for the current session.
|
||||||
|
//
|
||||||
|
// GET /session/roles
|
||||||
|
SessionRoles(ctx context.Context) (*Roles, error)
|
||||||
|
// SessionUser implements sessionUser operation.
|
||||||
|
//
|
||||||
|
// Get information about the currently logged in user.
|
||||||
|
//
|
||||||
|
// GET /session/user
|
||||||
|
SessionUser(ctx context.Context) (*User, error)
|
||||||
|
// SessionValidate implements sessionValidate operation.
|
||||||
|
//
|
||||||
|
// Ask if the current session is valid.
|
||||||
|
//
|
||||||
|
// GET /session/validate
|
||||||
|
SessionValidate(ctx context.Context) (bool, error)
|
||||||
// SetSubmissionCompleted implements setSubmissionCompleted operation.
|
// SetSubmissionCompleted implements setSubmissionCompleted operation.
|
||||||
//
|
//
|
||||||
// Retrieve map with ID.
|
// Called by maptest when a player completes the map.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/completed
|
// POST /submissions/{SubmissionID}/completed
|
||||||
SetSubmissionCompleted(ctx context.Context, params SetSubmissionCompletedParams) error
|
SetSubmissionCompleted(ctx context.Context, params SetSubmissionCompletedParams) error
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ type UnimplementedHandler struct{}
|
|||||||
|
|
||||||
var _ Handler = UnimplementedHandler{}
|
var _ Handler = UnimplementedHandler{}
|
||||||
|
|
||||||
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer manually resets validating softlock and changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reset-validating
|
||||||
|
func (UnimplementedHandler) ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// ActionSubmissionReject implements actionSubmissionReject operation.
|
// ActionSubmissionReject implements actionSubmissionReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -31,6 +40,15 @@ func (UnimplementedHandler) ActionSubmissionRequestChanges(ctx context.Context,
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionRetryValidate implements actionSubmissionRetryValidate operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/retry-validate
|
||||||
|
func (UnimplementedHandler) ActionSubmissionRetryValidate(ctx context.Context, params ActionSubmissionRetryValidateParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// ActionSubmissionRevoke implements actionSubmissionRevoke operation.
|
// ActionSubmissionRevoke implements actionSubmissionRevoke operation.
|
||||||
//
|
//
|
||||||
// Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction.
|
// Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction.
|
||||||
@@ -60,13 +78,22 @@ func (UnimplementedHandler) ActionSubmissionTriggerUpload(ctx context.Context, p
|
|||||||
|
|
||||||
// ActionSubmissionTriggerValidate implements actionSubmissionTriggerValidate operation.
|
// ActionSubmissionTriggerValidate implements actionSubmissionTriggerValidate operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating.
|
// Role Reviewer triggers validation and changes status from Submitted -> Validating.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/trigger-validate
|
// POST /submissions/{SubmissionID}/status/trigger-validate
|
||||||
func (UnimplementedHandler) ActionSubmissionTriggerValidate(ctx context.Context, params ActionSubmissionTriggerValidateParams) error {
|
func (UnimplementedHandler) ActionSubmissionTriggerValidate(ctx context.Context, params ActionSubmissionTriggerValidateParams) error {
|
||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionValidated implements actionSubmissionValidated operation.
|
||||||
|
//
|
||||||
|
// Role Admin manually resets uploading softlock and changes status from Uploading -> Validated.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reset-uploading
|
||||||
|
func (UnimplementedHandler) ActionSubmissionValidated(ctx context.Context, params ActionSubmissionValidatedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// CreateScript implements createScript operation.
|
// CreateScript implements createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -166,9 +193,45 @@ func (UnimplementedHandler) ListSubmissions(ctx context.Context, params ListSubm
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReleaseSubmissions implements releaseSubmissions operation.
|
||||||
|
//
|
||||||
|
// Release a set of uploaded maps.
|
||||||
|
//
|
||||||
|
// POST /release-submissions
|
||||||
|
func (UnimplementedHandler) ReleaseSubmissions(ctx context.Context, req []ReleaseInfo) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionRoles implements sessionRoles operation.
|
||||||
|
//
|
||||||
|
// Get list of roles for the current session.
|
||||||
|
//
|
||||||
|
// GET /session/roles
|
||||||
|
func (UnimplementedHandler) SessionRoles(ctx context.Context) (r *Roles, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionUser implements sessionUser operation.
|
||||||
|
//
|
||||||
|
// Get information about the currently logged in user.
|
||||||
|
//
|
||||||
|
// GET /session/user
|
||||||
|
func (UnimplementedHandler) SessionUser(ctx context.Context) (r *User, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionValidate implements sessionValidate operation.
|
||||||
|
//
|
||||||
|
// Ask if the current session is valid.
|
||||||
|
//
|
||||||
|
// GET /session/validate
|
||||||
|
func (UnimplementedHandler) SessionValidate(ctx context.Context) (r bool, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// SetSubmissionCompleted implements setSubmissionCompleted operation.
|
// SetSubmissionCompleted implements setSubmissionCompleted operation.
|
||||||
//
|
//
|
||||||
// Retrieve map with ID.
|
// Called by maptest when a player completes the map.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/completed
|
// POST /submissions/{SubmissionID}/completed
|
||||||
func (UnimplementedHandler) SetSubmissionCompleted(ctx context.Context, params SetSubmissionCompletedParams) error {
|
func (UnimplementedHandler) SetSubmissionCompleted(ctx context.Context, params SetSubmissionCompletedParams) error {
|
||||||
|
|||||||
@@ -266,6 +266,25 @@ func (s *Submission) Validate() error {
|
|||||||
Error: err,
|
Error: err,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.String{
|
||||||
|
MinLength: 0,
|
||||||
|
MinLengthSet: false,
|
||||||
|
MaxLength: 256,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(s.StatusMessage)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "StatusMessage",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
if len(failures) > 0 {
|
if len(failures) > 0 {
|
||||||
return &validate.Error{Fields: failures}
|
return &validate.Error{Fields: failures}
|
||||||
}
|
}
|
||||||
@@ -321,3 +340,53 @@ func (s *SubmissionCreate) Validate() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *User) Validate() error {
|
||||||
|
if s == nil {
|
||||||
|
return validate.ErrNilPointer
|
||||||
|
}
|
||||||
|
|
||||||
|
var failures []validate.FieldError
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.String{
|
||||||
|
MinLength: 0,
|
||||||
|
MinLengthSet: false,
|
||||||
|
MaxLength: 128,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(s.Username)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "Username",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.String{
|
||||||
|
MinLength: 0,
|
||||||
|
MinLengthSet: false,
|
||||||
|
MaxLength: 256,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(s.AvatarURL)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "AvatarURL",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/auth"
|
"git.itzana.me/strafesnet/go-grpc/auth"
|
||||||
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore/gormstore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore/gormstore"
|
||||||
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
|
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
|
||||||
@@ -77,6 +78,12 @@ func NewServeCommand() *cli.Command {
|
|||||||
EnvVars: []string{"AUTH_RPC_HOST"},
|
EnvVars: []string{"AUTH_RPC_HOST"},
|
||||||
Value: "auth-service:8090",
|
Value: "auth-service:8090",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "data-rpc-host",
|
||||||
|
Usage: "Host of data rpc",
|
||||||
|
EnvVars: []string{"DATA_RPC_HOST"},
|
||||||
|
Value: "data-service:9000",
|
||||||
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "nats-host",
|
Name: "nats-host",
|
||||||
Usage: "Host of nats",
|
Usage: "Host of nats",
|
||||||
@@ -110,12 +117,18 @@ func serve(ctx *cli.Context) error {
|
|||||||
log.WithError(err).Fatal("failed to add stream")
|
log.WithError(err).Fatal("failed to add stream")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// connect to main game database
|
||||||
|
conn, err := grpc.Dial(ctx.String("data-rpc-host"), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
svc := &service.Service{
|
svc := &service.Service{
|
||||||
DB: db,
|
DB: db,
|
||||||
Nats: js,
|
Nats: js,
|
||||||
|
Client: maps.NewMapsServiceClient(conn),
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := grpc.Dial(ctx.String("auth-rpc-host"), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
conn, err = grpc.Dial(ctx.String("auth-rpc-host"), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,16 @@ import (
|
|||||||
var (
|
var (
|
||||||
ErrNotExist = errors.New("resource does not exist")
|
ErrNotExist = errors.New("resource does not exist")
|
||||||
ErroNoRowsAffected = errors.New("query did not affect any rows")
|
ErroNoRowsAffected = errors.New("query did not affect any rows")
|
||||||
|
ErrInvalidListSort = errors.New("invalid list sort parameter [1,2,3,4]")
|
||||||
|
)
|
||||||
|
|
||||||
|
type ListSort uint32
|
||||||
|
const (
|
||||||
|
ListSortDisabled ListSort = 0
|
||||||
|
ListSortDisplayNameAscending ListSort = 1
|
||||||
|
ListSortDisplayNameDescending ListSort = 2
|
||||||
|
ListSortDateAscending ListSort = 3
|
||||||
|
ListSortDateDescending ListSort = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
type Datastore interface {
|
type Datastore interface {
|
||||||
@@ -22,10 +32,10 @@ type Submissions interface {
|
|||||||
GetList(ctx context.Context, id []int64) ([]model.Submission, error)
|
GetList(ctx context.Context, id []int64) ([]model.Submission, error)
|
||||||
Create(ctx context.Context, smap model.Submission) (model.Submission, error)
|
Create(ctx context.Context, smap model.Submission) (model.Submission, error)
|
||||||
Update(ctx context.Context, id int64, values OptionalMap) error
|
Update(ctx context.Context, id int64, values OptionalMap) error
|
||||||
IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values OptionalMap) error
|
IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.SubmissionStatus, values OptionalMap) error
|
||||||
IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.Status, values OptionalMap) (model.Submission, error)
|
IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.SubmissionStatus, values OptionalMap) (model.Submission, error)
|
||||||
Delete(ctx context.Context, id int64) error
|
Delete(ctx context.Context, id int64) error
|
||||||
List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Submission, error)
|
List(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) ([]model.Submission, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Scripts interface {
|
type Scripts interface {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func (env *Scripts) Update(ctx context.Context, id int64, values datastore.Optio
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the update can only occur if the status matches one of the provided values.
|
// the update can only occur if the status matches one of the provided values.
|
||||||
func (env *Scripts) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values datastore.OptionalMap) error {
|
func (env *Scripts) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.SubmissionStatus, values datastore.OptionalMap) error {
|
||||||
if err := env.db.Model(&model.Script{}).Where("id = ?", id).Where("status IN ?", statuses).Updates(values.Map()).Error; err != nil {
|
if err := env.db.Model(&model.Script{}).Where("id = ?", id).Where("status IN ?", statuses).Updates(values.Map()).Error; err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
return datastore.ErrNotExist
|
return datastore.ErrNotExist
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func (env *Submissions) Update(ctx context.Context, id int64, values datastore.O
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the update can only occur if the status matches one of the provided values.
|
// the update can only occur if the status matches one of the provided values.
|
||||||
func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values datastore.OptionalMap) error {
|
func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.SubmissionStatus, values datastore.OptionalMap) error {
|
||||||
if err := env.db.Model(&model.Submission{}).Where("id = ?", id).Where("status_id IN ?", statuses).Updates(values.Map()).Error; err != nil {
|
if err := env.db.Model(&model.Submission{}).Where("id = ?", id).Where("status_id IN ?", statuses).Updates(values.Map()).Error; err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
return datastore.ErrNotExist
|
return datastore.ErrNotExist
|
||||||
@@ -67,7 +67,7 @@ func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, status
|
|||||||
|
|
||||||
// the update can only occur if the status matches one of the provided values.
|
// the update can only occur if the status matches one of the provided values.
|
||||||
// returns the updated value
|
// returns the updated value
|
||||||
func (env *Submissions) IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.Status, values datastore.OptionalMap) (model.Submission, error) {
|
func (env *Submissions) IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.SubmissionStatus, values datastore.OptionalMap) (model.Submission, error) {
|
||||||
var submission model.Submission
|
var submission model.Submission
|
||||||
result := env.db.Model(&submission).
|
result := env.db.Model(&submission).
|
||||||
Clauses(clause.Returning{}).
|
Clauses(clause.Returning{}).
|
||||||
@@ -99,9 +99,32 @@ func (env *Submissions) Delete(ctx context.Context, id int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (env *Submissions) List(ctx context.Context, filters datastore.OptionalMap, page model.Page) ([]model.Submission, error) {
|
func (env *Submissions) List(ctx context.Context, filters datastore.OptionalMap, page model.Page, sort datastore.ListSort) ([]model.Submission, error) {
|
||||||
var maps []model.Submission
|
var maps []model.Submission
|
||||||
if err := env.db.Where(filters.Map()).Offset(int((page.Number - 1) * page.Size)).Limit(int(page.Size)).Find(&maps).Error; err != nil {
|
|
||||||
|
db := env.db
|
||||||
|
|
||||||
|
switch sort {
|
||||||
|
case datastore.ListSortDisabled:
|
||||||
|
// No sort
|
||||||
|
break
|
||||||
|
case datastore.ListSortDisplayNameAscending:
|
||||||
|
db=db.Order("display_name ASC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDisplayNameDescending:
|
||||||
|
db=db.Order("display_name DESC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDateAscending:
|
||||||
|
db=db.Order("created_at ASC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDateDescending:
|
||||||
|
db=db.Order("created_at DESC")
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return nil, datastore.ErrInvalidListSort
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Where(filters.Map()).Offset(int((page.Number - 1) * page.Size)).Limit(int(page.Size)).Find(&maps).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ import (
|
|||||||
"github.com/ogen-go/ogen/uri"
|
"github.com/ogen-go/ogen/uri"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func trimTrailingSlashes(u *url.URL) {
|
||||||
|
u.Path = strings.TrimRight(u.Path, "/")
|
||||||
|
u.RawPath = strings.TrimRight(u.RawPath, "/")
|
||||||
|
}
|
||||||
|
|
||||||
// Invoker invokes operations described by OpenAPI v3 specification.
|
// Invoker invokes operations described by OpenAPI v3 specification.
|
||||||
type Invoker interface {
|
type Invoker interface {
|
||||||
// ActionSubmissionAccepted invokes actionSubmissionAccepted operation.
|
// ActionSubmissionAccepted invokes actionSubmissionAccepted operation.
|
||||||
@@ -29,12 +34,6 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/validator-failed
|
// POST /submissions/{SubmissionID}/status/validator-failed
|
||||||
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
||||||
// ActionSubmissionReleased invokes actionSubmissionReleased operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Releaser changes status from releasing -> released.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/releaser-released
|
|
||||||
ActionSubmissionReleased(ctx context.Context, params ActionSubmissionReleasedParams) error
|
|
||||||
// ActionSubmissionUploaded invokes actionSubmissionUploaded operation.
|
// ActionSubmissionUploaded invokes actionSubmissionUploaded operation.
|
||||||
//
|
//
|
||||||
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
@@ -77,12 +76,12 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// GET /scripts
|
// GET /scripts
|
||||||
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
|
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
|
||||||
// UpdateSubmissionModel invokes updateSubmissionModel operation.
|
// UpdateSubmissionValidatedModel invokes updateSubmissionValidatedModel operation.
|
||||||
//
|
//
|
||||||
// Update model following role restrictions.
|
// Update validated model.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/model
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
UpdateSubmissionModel(ctx context.Context, params UpdateSubmissionModelParams) error
|
UpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client implements OAS client.
|
// Client implements OAS client.
|
||||||
@@ -99,11 +98,6 @@ var _ Handler = struct {
|
|||||||
*Client
|
*Client
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
func trimTrailingSlashes(u *url.URL) {
|
|
||||||
u.Path = strings.TrimRight(u.Path, "/")
|
|
||||||
u.RawPath = strings.TrimRight(u.RawPath, "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient initializes new Client defined by OAS.
|
// NewClient initializes new Client defined by OAS.
|
||||||
func NewClient(serverURL string, opts ...ClientOption) (*Client, error) {
|
func NewClient(serverURL string, opts ...ClientOption) (*Client, error) {
|
||||||
u, err := url.Parse(serverURL)
|
u, err := url.Parse(serverURL)
|
||||||
@@ -206,6 +200,24 @@ func (c *Client) sendActionSubmissionAccepted(ctx context.Context, params Action
|
|||||||
pathParts[2] = "/status/validator-failed"
|
pathParts[2] = "/status/validator-failed"
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeQueryParams"
|
||||||
|
q := uri.NewQueryEncoder()
|
||||||
|
{
|
||||||
|
// Encode "StatusMessage" parameter.
|
||||||
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
|
Name: "StatusMessage",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
|
return e.EncodeValue(conv.StringToString(params.StatusMessage))
|
||||||
|
}); err != nil {
|
||||||
|
return res, errors.Wrap(err, "encode query")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.RawQuery = q.Values().Encode()
|
||||||
|
|
||||||
stage = "EncodeRequest"
|
stage = "EncodeRequest"
|
||||||
r, err := ht.NewRequest(ctx, "POST", u)
|
r, err := ht.NewRequest(ctx, "POST", u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -228,97 +240,6 @@ func (c *Client) sendActionSubmissionAccepted(ctx context.Context, params Action
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionReleased invokes actionSubmissionReleased operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Releaser changes status from releasing -> released.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/releaser-released
|
|
||||||
func (c *Client) ActionSubmissionReleased(ctx context.Context, params ActionSubmissionReleasedParams) error {
|
|
||||||
_, err := c.sendActionSubmissionReleased(ctx, params)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) sendActionSubmissionReleased(ctx context.Context, params ActionSubmissionReleasedParams) (res *ActionSubmissionReleasedNoContent, err error) {
|
|
||||||
otelAttrs := []attribute.KeyValue{
|
|
||||||
otelogen.OperationID("actionSubmissionReleased"),
|
|
||||||
semconv.HTTPRequestMethodKey.String("POST"),
|
|
||||||
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/releaser-released"),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run stopwatch.
|
|
||||||
startTime := time.Now()
|
|
||||||
defer func() {
|
|
||||||
// Use floating point division here for higher precision (instead of Millisecond method).
|
|
||||||
elapsedDuration := time.Since(startTime)
|
|
||||||
c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...))
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Increment request counter.
|
|
||||||
c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
|
|
||||||
|
|
||||||
// Start a span for this request.
|
|
||||||
ctx, span := c.cfg.Tracer.Start(ctx, ActionSubmissionReleasedOperation,
|
|
||||||
trace.WithAttributes(otelAttrs...),
|
|
||||||
clientSpanKind,
|
|
||||||
)
|
|
||||||
// Track stage for error reporting.
|
|
||||||
var stage string
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
span.RecordError(err)
|
|
||||||
span.SetStatus(codes.Error, stage)
|
|
||||||
c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
|
|
||||||
}
|
|
||||||
span.End()
|
|
||||||
}()
|
|
||||||
|
|
||||||
stage = "BuildURL"
|
|
||||||
u := uri.Clone(c.requestURL(ctx))
|
|
||||||
var pathParts [3]string
|
|
||||||
pathParts[0] = "/submissions/"
|
|
||||||
{
|
|
||||||
// Encode "SubmissionID" parameter.
|
|
||||||
e := uri.NewPathEncoder(uri.PathEncoderConfig{
|
|
||||||
Param: "SubmissionID",
|
|
||||||
Style: uri.PathStyleSimple,
|
|
||||||
Explode: false,
|
|
||||||
})
|
|
||||||
if err := func() error {
|
|
||||||
return e.EncodeValue(conv.Int64ToString(params.SubmissionID))
|
|
||||||
}(); err != nil {
|
|
||||||
return res, errors.Wrap(err, "encode path")
|
|
||||||
}
|
|
||||||
encoded, err := e.Result()
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "encode path")
|
|
||||||
}
|
|
||||||
pathParts[1] = encoded
|
|
||||||
}
|
|
||||||
pathParts[2] = "/status/releaser-released"
|
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
|
||||||
|
|
||||||
stage = "EncodeRequest"
|
|
||||||
r, err := ht.NewRequest(ctx, "POST", u)
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "create request")
|
|
||||||
}
|
|
||||||
|
|
||||||
stage = "SendRequest"
|
|
||||||
resp, err := c.cfg.Client.Do(r)
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "do request")
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
stage = "DecodeResponse"
|
|
||||||
result, err := decodeActionSubmissionReleasedResponse(resp)
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "decode response")
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionUploaded invokes actionSubmissionUploaded operation.
|
// ActionSubmissionUploaded invokes actionSubmissionUploaded operation.
|
||||||
//
|
//
|
||||||
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
@@ -391,18 +312,15 @@ func (c *Client) sendActionSubmissionUploaded(ctx context.Context, params Action
|
|||||||
stage = "EncodeQueryParams"
|
stage = "EncodeQueryParams"
|
||||||
q := uri.NewQueryEncoder()
|
q := uri.NewQueryEncoder()
|
||||||
{
|
{
|
||||||
// Encode "TargetAssetID" parameter.
|
// Encode "UploadedAssetID" parameter.
|
||||||
cfg := uri.QueryParameterEncodingConfig{
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
Name: "TargetAssetID",
|
Name: "UploadedAssetID",
|
||||||
Style: uri.QueryStyleForm,
|
Style: uri.QueryStyleForm,
|
||||||
Explode: true,
|
Explode: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
if val, ok := params.TargetAssetID.Get(); ok {
|
return e.EncodeValue(conv.Int64ToString(params.UploadedAssetID))
|
||||||
return e.EncodeValue(conv.Int64ToString(val))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return res, errors.Wrap(err, "encode query")
|
return res, errors.Wrap(err, "encode query")
|
||||||
}
|
}
|
||||||
@@ -1089,21 +1007,21 @@ func (c *Client) sendListScripts(ctx context.Context, params ListScriptsParams)
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSubmissionModel invokes updateSubmissionModel operation.
|
// UpdateSubmissionValidatedModel invokes updateSubmissionValidatedModel operation.
|
||||||
//
|
//
|
||||||
// Update model following role restrictions.
|
// Update validated model.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/model
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
func (c *Client) UpdateSubmissionModel(ctx context.Context, params UpdateSubmissionModelParams) error {
|
func (c *Client) UpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) error {
|
||||||
_, err := c.sendUpdateSubmissionModel(ctx, params)
|
_, err := c.sendUpdateSubmissionValidatedModel(ctx, params)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) sendUpdateSubmissionModel(ctx context.Context, params UpdateSubmissionModelParams) (res *UpdateSubmissionModelNoContent, err error) {
|
func (c *Client) sendUpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) (res *UpdateSubmissionValidatedModelNoContent, err error) {
|
||||||
otelAttrs := []attribute.KeyValue{
|
otelAttrs := []attribute.KeyValue{
|
||||||
otelogen.OperationID("updateSubmissionModel"),
|
otelogen.OperationID("updateSubmissionValidatedModel"),
|
||||||
semconv.HTTPRequestMethodKey.String("POST"),
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/model"),
|
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/validated-model"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run stopwatch.
|
// Run stopwatch.
|
||||||
@@ -1118,7 +1036,7 @@ func (c *Client) sendUpdateSubmissionModel(ctx context.Context, params UpdateSub
|
|||||||
c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
|
c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
|
||||||
|
|
||||||
// Start a span for this request.
|
// Start a span for this request.
|
||||||
ctx, span := c.cfg.Tracer.Start(ctx, UpdateSubmissionModelOperation,
|
ctx, span := c.cfg.Tracer.Start(ctx, UpdateSubmissionValidatedModelOperation,
|
||||||
trace.WithAttributes(otelAttrs...),
|
trace.WithAttributes(otelAttrs...),
|
||||||
clientSpanKind,
|
clientSpanKind,
|
||||||
)
|
)
|
||||||
@@ -1155,35 +1073,35 @@ func (c *Client) sendUpdateSubmissionModel(ctx context.Context, params UpdateSub
|
|||||||
}
|
}
|
||||||
pathParts[1] = encoded
|
pathParts[1] = encoded
|
||||||
}
|
}
|
||||||
pathParts[2] = "/model"
|
pathParts[2] = "/validated-model"
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
stage = "EncodeQueryParams"
|
stage = "EncodeQueryParams"
|
||||||
q := uri.NewQueryEncoder()
|
q := uri.NewQueryEncoder()
|
||||||
{
|
{
|
||||||
// Encode "ModelID" parameter.
|
// Encode "ValidatedModelID" parameter.
|
||||||
cfg := uri.QueryParameterEncodingConfig{
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
Name: "ModelID",
|
Name: "ValidatedModelID",
|
||||||
Style: uri.QueryStyleForm,
|
Style: uri.QueryStyleForm,
|
||||||
Explode: true,
|
Explode: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
return e.EncodeValue(conv.Int64ToString(params.ModelID))
|
return e.EncodeValue(conv.Int64ToString(params.ValidatedModelID))
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return res, errors.Wrap(err, "encode query")
|
return res, errors.Wrap(err, "encode query")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Encode "VersionID" parameter.
|
// Encode "ValidatedModelVersion" parameter.
|
||||||
cfg := uri.QueryParameterEncodingConfig{
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
Name: "VersionID",
|
Name: "ValidatedModelVersion",
|
||||||
Style: uri.QueryStyleForm,
|
Style: uri.QueryStyleForm,
|
||||||
Explode: true,
|
Explode: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
return e.EncodeValue(conv.Int64ToString(params.VersionID))
|
return e.EncodeValue(conv.Int64ToString(params.ValidatedModelVersion))
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return res, errors.Wrap(err, "encode query")
|
return res, errors.Wrap(err, "encode query")
|
||||||
}
|
}
|
||||||
@@ -1204,7 +1122,7 @@ func (c *Client) sendUpdateSubmissionModel(ctx context.Context, params UpdateSub
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
stage = "DecodeResponse"
|
stage = "DecodeResponse"
|
||||||
result, err := decodeUpdateSubmissionModelResponse(resp)
|
result, err := decodeUpdateSubmissionValidatedModelResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, errors.Wrap(err, "decode response")
|
return res, errors.Wrap(err, "decode response")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ func (s *Server) handleActionSubmissionAcceptedRequest(args [1]string, argsEscap
|
|||||||
Name: "SubmissionID",
|
Name: "SubmissionID",
|
||||||
In: "path",
|
In: "path",
|
||||||
}: params.SubmissionID,
|
}: params.SubmissionID,
|
||||||
|
{
|
||||||
|
Name: "StatusMessage",
|
||||||
|
In: "query",
|
||||||
|
}: params.StatusMessage,
|
||||||
},
|
},
|
||||||
Raw: r,
|
Raw: r,
|
||||||
}
|
}
|
||||||
@@ -179,155 +183,6 @@ func (s *Server) handleActionSubmissionAcceptedRequest(args [1]string, argsEscap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleActionSubmissionReleasedRequest handles actionSubmissionReleased operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Releaser changes status from releasing -> released.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/releaser-released
|
|
||||||
func (s *Server) handleActionSubmissionReleasedRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
|
|
||||||
statusWriter := &codeRecorder{ResponseWriter: w}
|
|
||||||
w = statusWriter
|
|
||||||
otelAttrs := []attribute.KeyValue{
|
|
||||||
otelogen.OperationID("actionSubmissionReleased"),
|
|
||||||
semconv.HTTPRequestMethodKey.String("POST"),
|
|
||||||
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/releaser-released"),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start a span for this request.
|
|
||||||
ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionReleasedOperation,
|
|
||||||
trace.WithAttributes(otelAttrs...),
|
|
||||||
serverSpanKind,
|
|
||||||
)
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// Add Labeler to context.
|
|
||||||
labeler := &Labeler{attrs: otelAttrs}
|
|
||||||
ctx = contextWithLabeler(ctx, labeler)
|
|
||||||
|
|
||||||
// Run stopwatch.
|
|
||||||
startTime := time.Now()
|
|
||||||
defer func() {
|
|
||||||
elapsedDuration := time.Since(startTime)
|
|
||||||
|
|
||||||
attrSet := labeler.AttributeSet()
|
|
||||||
attrs := attrSet.ToSlice()
|
|
||||||
code := statusWriter.status
|
|
||||||
if code != 0 {
|
|
||||||
codeAttr := semconv.HTTPResponseStatusCode(code)
|
|
||||||
attrs = append(attrs, codeAttr)
|
|
||||||
span.SetAttributes(codeAttr)
|
|
||||||
}
|
|
||||||
attrOpt := metric.WithAttributes(attrs...)
|
|
||||||
|
|
||||||
// Increment request counter.
|
|
||||||
s.requests.Add(ctx, 1, attrOpt)
|
|
||||||
|
|
||||||
// Use floating point division here for higher precision (instead of Millisecond method).
|
|
||||||
s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt)
|
|
||||||
}()
|
|
||||||
|
|
||||||
var (
|
|
||||||
recordError = func(stage string, err error) {
|
|
||||||
span.RecordError(err)
|
|
||||||
|
|
||||||
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
|
|
||||||
// Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges,
|
|
||||||
// unless there was another error (e.g., network error receiving the response body; or 3xx codes with
|
|
||||||
// max redirects exceeded), in which case status MUST be set to Error.
|
|
||||||
code := statusWriter.status
|
|
||||||
if code >= 100 && code < 500 {
|
|
||||||
span.SetStatus(codes.Error, stage)
|
|
||||||
}
|
|
||||||
|
|
||||||
attrSet := labeler.AttributeSet()
|
|
||||||
attrs := attrSet.ToSlice()
|
|
||||||
if code != 0 {
|
|
||||||
attrs = append(attrs, semconv.HTTPResponseStatusCode(code))
|
|
||||||
}
|
|
||||||
|
|
||||||
s.errors.Add(ctx, 1, metric.WithAttributes(attrs...))
|
|
||||||
}
|
|
||||||
err error
|
|
||||||
opErrContext = ogenerrors.OperationContext{
|
|
||||||
Name: ActionSubmissionReleasedOperation,
|
|
||||||
ID: "actionSubmissionReleased",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
params, err := decodeActionSubmissionReleasedParams(args, argsEscaped, r)
|
|
||||||
if err != nil {
|
|
||||||
err = &ogenerrors.DecodeParamsError{
|
|
||||||
OperationContext: opErrContext,
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
defer recordError("DecodeParams", err)
|
|
||||||
s.cfg.ErrorHandler(ctx, w, r, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var response *ActionSubmissionReleasedNoContent
|
|
||||||
if m := s.cfg.Middleware; m != nil {
|
|
||||||
mreq := middleware.Request{
|
|
||||||
Context: ctx,
|
|
||||||
OperationName: ActionSubmissionReleasedOperation,
|
|
||||||
OperationSummary: "(Internal endpoint) Role Releaser changes status from releasing -> released",
|
|
||||||
OperationID: "actionSubmissionReleased",
|
|
||||||
Body: nil,
|
|
||||||
Params: middleware.Parameters{
|
|
||||||
{
|
|
||||||
Name: "SubmissionID",
|
|
||||||
In: "path",
|
|
||||||
}: params.SubmissionID,
|
|
||||||
},
|
|
||||||
Raw: r,
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
|
||||||
Request = struct{}
|
|
||||||
Params = ActionSubmissionReleasedParams
|
|
||||||
Response = *ActionSubmissionReleasedNoContent
|
|
||||||
)
|
|
||||||
response, err = middleware.HookMiddleware[
|
|
||||||
Request,
|
|
||||||
Params,
|
|
||||||
Response,
|
|
||||||
](
|
|
||||||
m,
|
|
||||||
mreq,
|
|
||||||
unpackActionSubmissionReleasedParams,
|
|
||||||
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
|
||||||
err = s.h.ActionSubmissionReleased(ctx, params)
|
|
||||||
return response, err
|
|
||||||
},
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
err = s.h.ActionSubmissionReleased(ctx, params)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if errRes, ok := errors.Into[*ErrorStatusCode](err); ok {
|
|
||||||
if err := encodeErrorResponse(errRes, w, span); err != nil {
|
|
||||||
defer recordError("Internal", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, ht.ErrNotImplemented) {
|
|
||||||
s.cfg.ErrorHandler(ctx, w, r, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil {
|
|
||||||
defer recordError("Internal", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := encodeActionSubmissionReleasedResponse(response, w, span); err != nil {
|
|
||||||
defer recordError("EncodeResponse", err)
|
|
||||||
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
|
|
||||||
s.cfg.ErrorHandler(ctx, w, r, err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleActionSubmissionUploadedRequest handles actionSubmissionUploaded operation.
|
// handleActionSubmissionUploadedRequest handles actionSubmissionUploaded operation.
|
||||||
//
|
//
|
||||||
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
@@ -427,9 +282,9 @@ func (s *Server) handleActionSubmissionUploadedRequest(args [1]string, argsEscap
|
|||||||
In: "path",
|
In: "path",
|
||||||
}: params.SubmissionID,
|
}: params.SubmissionID,
|
||||||
{
|
{
|
||||||
Name: "TargetAssetID",
|
Name: "UploadedAssetID",
|
||||||
In: "query",
|
In: "query",
|
||||||
}: params.TargetAssetID,
|
}: params.UploadedAssetID,
|
||||||
},
|
},
|
||||||
Raw: r,
|
Raw: r,
|
||||||
}
|
}
|
||||||
@@ -1411,22 +1266,22 @@ func (s *Server) handleListScriptsRequest(args [0]string, argsEscaped bool, w ht
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleUpdateSubmissionModelRequest handles updateSubmissionModel operation.
|
// handleUpdateSubmissionValidatedModelRequest handles updateSubmissionValidatedModel operation.
|
||||||
//
|
//
|
||||||
// Update model following role restrictions.
|
// Update validated model.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/model
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
func (s *Server) handleUpdateSubmissionModelRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
|
func (s *Server) handleUpdateSubmissionValidatedModelRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
|
||||||
statusWriter := &codeRecorder{ResponseWriter: w}
|
statusWriter := &codeRecorder{ResponseWriter: w}
|
||||||
w = statusWriter
|
w = statusWriter
|
||||||
otelAttrs := []attribute.KeyValue{
|
otelAttrs := []attribute.KeyValue{
|
||||||
otelogen.OperationID("updateSubmissionModel"),
|
otelogen.OperationID("updateSubmissionValidatedModel"),
|
||||||
semconv.HTTPRequestMethodKey.String("POST"),
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/model"),
|
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/validated-model"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a span for this request.
|
// Start a span for this request.
|
||||||
ctx, span := s.cfg.Tracer.Start(r.Context(), UpdateSubmissionModelOperation,
|
ctx, span := s.cfg.Tracer.Start(r.Context(), UpdateSubmissionValidatedModelOperation,
|
||||||
trace.WithAttributes(otelAttrs...),
|
trace.WithAttributes(otelAttrs...),
|
||||||
serverSpanKind,
|
serverSpanKind,
|
||||||
)
|
)
|
||||||
@@ -1481,11 +1336,11 @@ func (s *Server) handleUpdateSubmissionModelRequest(args [1]string, argsEscaped
|
|||||||
}
|
}
|
||||||
err error
|
err error
|
||||||
opErrContext = ogenerrors.OperationContext{
|
opErrContext = ogenerrors.OperationContext{
|
||||||
Name: UpdateSubmissionModelOperation,
|
Name: UpdateSubmissionValidatedModelOperation,
|
||||||
ID: "updateSubmissionModel",
|
ID: "updateSubmissionValidatedModel",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
params, err := decodeUpdateSubmissionModelParams(args, argsEscaped, r)
|
params, err := decodeUpdateSubmissionValidatedModelParams(args, argsEscaped, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = &ogenerrors.DecodeParamsError{
|
err = &ogenerrors.DecodeParamsError{
|
||||||
OperationContext: opErrContext,
|
OperationContext: opErrContext,
|
||||||
@@ -1496,13 +1351,13 @@ func (s *Server) handleUpdateSubmissionModelRequest(args [1]string, argsEscaped
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var response *UpdateSubmissionModelNoContent
|
var response *UpdateSubmissionValidatedModelNoContent
|
||||||
if m := s.cfg.Middleware; m != nil {
|
if m := s.cfg.Middleware; m != nil {
|
||||||
mreq := middleware.Request{
|
mreq := middleware.Request{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
OperationName: UpdateSubmissionModelOperation,
|
OperationName: UpdateSubmissionValidatedModelOperation,
|
||||||
OperationSummary: "Update model following role restrictions",
|
OperationSummary: "Update validated model",
|
||||||
OperationID: "updateSubmissionModel",
|
OperationID: "updateSubmissionValidatedModel",
|
||||||
Body: nil,
|
Body: nil,
|
||||||
Params: middleware.Parameters{
|
Params: middleware.Parameters{
|
||||||
{
|
{
|
||||||
@@ -1510,21 +1365,21 @@ func (s *Server) handleUpdateSubmissionModelRequest(args [1]string, argsEscaped
|
|||||||
In: "path",
|
In: "path",
|
||||||
}: params.SubmissionID,
|
}: params.SubmissionID,
|
||||||
{
|
{
|
||||||
Name: "ModelID",
|
Name: "ValidatedModelID",
|
||||||
In: "query",
|
In: "query",
|
||||||
}: params.ModelID,
|
}: params.ValidatedModelID,
|
||||||
{
|
{
|
||||||
Name: "VersionID",
|
Name: "ValidatedModelVersion",
|
||||||
In: "query",
|
In: "query",
|
||||||
}: params.VersionID,
|
}: params.ValidatedModelVersion,
|
||||||
},
|
},
|
||||||
Raw: r,
|
Raw: r,
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Request = struct{}
|
Request = struct{}
|
||||||
Params = UpdateSubmissionModelParams
|
Params = UpdateSubmissionValidatedModelParams
|
||||||
Response = *UpdateSubmissionModelNoContent
|
Response = *UpdateSubmissionValidatedModelNoContent
|
||||||
)
|
)
|
||||||
response, err = middleware.HookMiddleware[
|
response, err = middleware.HookMiddleware[
|
||||||
Request,
|
Request,
|
||||||
@@ -1533,14 +1388,14 @@ func (s *Server) handleUpdateSubmissionModelRequest(args [1]string, argsEscaped
|
|||||||
](
|
](
|
||||||
m,
|
m,
|
||||||
mreq,
|
mreq,
|
||||||
unpackUpdateSubmissionModelParams,
|
unpackUpdateSubmissionValidatedModelParams,
|
||||||
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
||||||
err = s.h.UpdateSubmissionModel(ctx, params)
|
err = s.h.UpdateSubmissionValidatedModel(ctx, params)
|
||||||
return response, err
|
return response, err
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
err = s.h.UpdateSubmissionModel(ctx, params)
|
err = s.h.UpdateSubmissionValidatedModel(ctx, params)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errRes, ok := errors.Into[*ErrorStatusCode](err); ok {
|
if errRes, ok := errors.Into[*ErrorStatusCode](err); ok {
|
||||||
@@ -1559,7 +1414,7 @@ func (s *Server) handleUpdateSubmissionModelRequest(args [1]string, argsEscaped
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := encodeUpdateSubmissionModelResponse(response, w, span); err != nil {
|
if err := encodeUpdateSubmissionValidatedModelResponse(response, w, span); err != nil {
|
||||||
defer recordError("EncodeResponse", err)
|
defer recordError("EncodeResponse", err)
|
||||||
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
|
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
|
||||||
s.cfg.ErrorHandler(ctx, w, r, err)
|
s.cfg.ErrorHandler(ctx, w, r, err)
|
||||||
|
|||||||
@@ -282,17 +282,22 @@ func (s *Script) encodeFields(e *jx.Encoder) {
|
|||||||
e.Str(s.Source)
|
e.Str(s.Source)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
e.FieldStart("SubmissionID")
|
e.FieldStart("ResourceType")
|
||||||
e.Int64(s.SubmissionID)
|
e.Int32(s.ResourceType)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("ResourceID")
|
||||||
|
e.Int64(s.ResourceID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfScript = [5]string{
|
var jsonFieldsNameOfScript = [6]string{
|
||||||
0: "ID",
|
0: "ID",
|
||||||
1: "Name",
|
1: "Name",
|
||||||
2: "Hash",
|
2: "Hash",
|
||||||
3: "Source",
|
3: "Source",
|
||||||
4: "SubmissionID",
|
4: "ResourceType",
|
||||||
|
5: "ResourceID",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes Script from json.
|
// Decode decodes Script from json.
|
||||||
@@ -352,17 +357,29 @@ func (s *Script) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"Source\"")
|
return errors.Wrap(err, "decode field \"Source\"")
|
||||||
}
|
}
|
||||||
case "SubmissionID":
|
case "ResourceType":
|
||||||
requiredBitSet[0] |= 1 << 4
|
requiredBitSet[0] |= 1 << 4
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
v, err := d.Int64()
|
v, err := d.Int32()
|
||||||
s.SubmissionID = int64(v)
|
s.ResourceType = int32(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"SubmissionID\"")
|
return errors.Wrap(err, "decode field \"ResourceType\"")
|
||||||
|
}
|
||||||
|
case "ResourceID":
|
||||||
|
requiredBitSet[0] |= 1 << 5
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Int64()
|
||||||
|
s.ResourceID = int64(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"ResourceID\"")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
@@ -374,7 +391,7 @@ func (s *Script) Decode(d *jx.Decoder) error {
|
|||||||
// Validate required fields.
|
// Validate required fields.
|
||||||
var failures []validate.FieldError
|
var failures []validate.FieldError
|
||||||
for i, mask := range [1]uint8{
|
for i, mask := range [1]uint8{
|
||||||
0b00011111,
|
0b00111111,
|
||||||
} {
|
} {
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
@@ -438,17 +455,22 @@ func (s *ScriptCreate) encodeFields(e *jx.Encoder) {
|
|||||||
e.Str(s.Source)
|
e.Str(s.Source)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if s.SubmissionID.Set {
|
e.FieldStart("ResourceType")
|
||||||
e.FieldStart("SubmissionID")
|
e.Int32(s.ResourceType)
|
||||||
s.SubmissionID.Encode(e)
|
}
|
||||||
|
{
|
||||||
|
if s.ResourceID.Set {
|
||||||
|
e.FieldStart("ResourceID")
|
||||||
|
s.ResourceID.Encode(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfScriptCreate = [3]string{
|
var jsonFieldsNameOfScriptCreate = [4]string{
|
||||||
0: "Name",
|
0: "Name",
|
||||||
1: "Source",
|
1: "Source",
|
||||||
2: "SubmissionID",
|
2: "ResourceType",
|
||||||
|
3: "ResourceID",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes ScriptCreate from json.
|
// Decode decodes ScriptCreate from json.
|
||||||
@@ -484,15 +506,27 @@ func (s *ScriptCreate) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"Source\"")
|
return errors.Wrap(err, "decode field \"Source\"")
|
||||||
}
|
}
|
||||||
case "SubmissionID":
|
case "ResourceType":
|
||||||
|
requiredBitSet[0] |= 1 << 2
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
s.SubmissionID.Reset()
|
v, err := d.Int32()
|
||||||
if err := s.SubmissionID.Decode(d); err != nil {
|
s.ResourceType = int32(v)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"SubmissionID\"")
|
return errors.Wrap(err, "decode field \"ResourceType\"")
|
||||||
|
}
|
||||||
|
case "ResourceID":
|
||||||
|
if err := func() error {
|
||||||
|
s.ResourceID.Reset()
|
||||||
|
if err := s.ResourceID.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"ResourceID\"")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
@@ -504,7 +538,7 @@ func (s *ScriptCreate) Decode(d *jx.Decoder) error {
|
|||||||
// Validate required fields.
|
// Validate required fields.
|
||||||
var failures []validate.FieldError
|
var failures []validate.FieldError
|
||||||
for i, mask := range [1]uint8{
|
for i, mask := range [1]uint8{
|
||||||
0b00000011,
|
0b00000111,
|
||||||
} {
|
} {
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
|
|||||||
@@ -6,14 +6,13 @@ package api
|
|||||||
type OperationName = string
|
type OperationName = string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
|
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
|
||||||
ActionSubmissionReleasedOperation OperationName = "ActionSubmissionReleased"
|
ActionSubmissionUploadedOperation OperationName = "ActionSubmissionUploaded"
|
||||||
ActionSubmissionUploadedOperation OperationName = "ActionSubmissionUploaded"
|
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
||||||
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
CreateScriptOperation OperationName = "CreateScript"
|
||||||
CreateScriptOperation OperationName = "CreateScript"
|
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
||||||
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
GetScriptOperation OperationName = "GetScript"
|
||||||
GetScriptOperation OperationName = "GetScript"
|
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
||||||
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
ListScriptsOperation OperationName = "ListScripts"
|
||||||
ListScriptsOperation OperationName = "ListScripts"
|
UpdateSubmissionValidatedModelOperation OperationName = "UpdateSubmissionValidatedModel"
|
||||||
UpdateSubmissionModelOperation OperationName = "UpdateSubmissionModel"
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ import (
|
|||||||
// ActionSubmissionAcceptedParams is parameters of actionSubmissionAccepted operation.
|
// ActionSubmissionAcceptedParams is parameters of actionSubmissionAccepted operation.
|
||||||
type ActionSubmissionAcceptedParams struct {
|
type ActionSubmissionAcceptedParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
|
StatusMessage string
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackActionSubmissionAcceptedParams(packed middleware.Parameters) (params ActionSubmissionAcceptedParams) {
|
func unpackActionSubmissionAcceptedParams(packed middleware.Parameters) (params ActionSubmissionAcceptedParams) {
|
||||||
@@ -29,10 +30,18 @@ func unpackActionSubmissionAcceptedParams(packed middleware.Parameters) (params
|
|||||||
}
|
}
|
||||||
params.SubmissionID = packed[key].(int64)
|
params.SubmissionID = packed[key].(int64)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "StatusMessage",
|
||||||
|
In: "query",
|
||||||
|
}
|
||||||
|
params.StatusMessage = packed[key].(string)
|
||||||
|
}
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeActionSubmissionAcceptedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionAcceptedParams, _ error) {
|
func decodeActionSubmissionAcceptedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionAcceptedParams, _ error) {
|
||||||
|
q := uri.NewQueryDecoder(r.URL.Query())
|
||||||
// Decode path: SubmissionID.
|
// Decode path: SubmissionID.
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
param := args[0]
|
param := args[0]
|
||||||
@@ -78,69 +87,55 @@ func decodeActionSubmissionAcceptedParams(args [1]string, argsEscaped bool, r *h
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return params, nil
|
// Decode query: StatusMessage.
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionReleasedParams is parameters of actionSubmissionReleased operation.
|
|
||||||
type ActionSubmissionReleasedParams struct {
|
|
||||||
// The unique identifier for a submission.
|
|
||||||
SubmissionID int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackActionSubmissionReleasedParams(packed middleware.Parameters) (params ActionSubmissionReleasedParams) {
|
|
||||||
{
|
|
||||||
key := middleware.ParameterKey{
|
|
||||||
Name: "SubmissionID",
|
|
||||||
In: "path",
|
|
||||||
}
|
|
||||||
params.SubmissionID = packed[key].(int64)
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeActionSubmissionReleasedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionReleasedParams, _ error) {
|
|
||||||
// Decode path: SubmissionID.
|
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
param := args[0]
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
if argsEscaped {
|
Name: "StatusMessage",
|
||||||
unescaped, err := url.PathUnescape(args[0])
|
Style: uri.QueryStyleForm,
|
||||||
if err != nil {
|
Explode: true,
|
||||||
return errors.Wrap(err, "unescape path")
|
|
||||||
}
|
|
||||||
param = unescaped
|
|
||||||
}
|
}
|
||||||
if len(param) > 0 {
|
|
||||||
d := uri.NewPathDecoder(uri.PathDecoderConfig{
|
|
||||||
Param: "SubmissionID",
|
|
||||||
Value: param,
|
|
||||||
Style: uri.PathStyleSimple,
|
|
||||||
Explode: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err := func() error {
|
if err := q.HasParam(cfg); err == nil {
|
||||||
|
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
||||||
val, err := d.DecodeValue()
|
val, err := d.DecodeValue()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := conv.ToInt64(val)
|
c, err := conv.ToString(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
params.SubmissionID = c
|
params.StatusMessage = c
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.String{
|
||||||
|
MinLength: 0,
|
||||||
|
MinLengthSet: true,
|
||||||
|
MaxLength: 4096,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(params.StatusMessage)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return params, &ogenerrors.DecodeParamError{
|
return params, &ogenerrors.DecodeParamError{
|
||||||
Name: "SubmissionID",
|
Name: "StatusMessage",
|
||||||
In: "path",
|
In: "query",
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,8 +145,8 @@ func decodeActionSubmissionReleasedParams(args [1]string, argsEscaped bool, r *h
|
|||||||
// ActionSubmissionUploadedParams is parameters of actionSubmissionUploaded operation.
|
// ActionSubmissionUploadedParams is parameters of actionSubmissionUploaded operation.
|
||||||
type ActionSubmissionUploadedParams struct {
|
type ActionSubmissionUploadedParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
TargetAssetID OptInt64
|
UploadedAssetID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackActionSubmissionUploadedParams(packed middleware.Parameters) (params ActionSubmissionUploadedParams) {
|
func unpackActionSubmissionUploadedParams(packed middleware.Parameters) (params ActionSubmissionUploadedParams) {
|
||||||
@@ -164,12 +159,10 @@ func unpackActionSubmissionUploadedParams(packed middleware.Parameters) (params
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
key := middleware.ParameterKey{
|
key := middleware.ParameterKey{
|
||||||
Name: "TargetAssetID",
|
Name: "UploadedAssetID",
|
||||||
In: "query",
|
In: "query",
|
||||||
}
|
}
|
||||||
if v, ok := packed[key]; ok {
|
params.UploadedAssetID = packed[key].(int64)
|
||||||
params.TargetAssetID = v.(OptInt64)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
@@ -221,43 +214,38 @@ func decodeActionSubmissionUploadedParams(args [1]string, argsEscaped bool, r *h
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decode query: TargetAssetID.
|
// Decode query: UploadedAssetID.
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
cfg := uri.QueryParameterDecodingConfig{
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
Name: "TargetAssetID",
|
Name: "UploadedAssetID",
|
||||||
Style: uri.QueryStyleForm,
|
Style: uri.QueryStyleForm,
|
||||||
Explode: true,
|
Explode: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := q.HasParam(cfg); err == nil {
|
if err := q.HasParam(cfg); err == nil {
|
||||||
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
||||||
var paramsDotTargetAssetIDVal int64
|
val, err := d.DecodeValue()
|
||||||
if err := func() error {
|
if err != nil {
|
||||||
val, err := d.DecodeValue()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := conv.ToInt64(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
paramsDotTargetAssetIDVal = c
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
params.TargetAssetID.SetTo(paramsDotTargetAssetIDVal)
|
|
||||||
|
c, err := conv.ToInt64(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
params.UploadedAssetID = c
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return params, &ogenerrors.DecodeParamError{
|
return params, &ogenerrors.DecodeParamError{
|
||||||
Name: "TargetAssetID",
|
Name: "UploadedAssetID",
|
||||||
In: "query",
|
In: "query",
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
@@ -496,7 +484,7 @@ func decodeListScriptPolicyParams(args [0]string, argsEscaped bool, r *http.Requ
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -549,7 +537,7 @@ func decodeListScriptPolicyParams(args [0]string, argsEscaped bool, r *http.Requ
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -817,7 +805,7 @@ func decodeListScriptsParams(args [0]string, argsEscaped bool, r *http.Request)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -870,7 +858,7 @@ func decodeListScriptsParams(args [0]string, argsEscaped bool, r *http.Request)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
@@ -1116,15 +1104,15 @@ func decodeListScriptsParams(args [0]string, argsEscaped bool, r *http.Request)
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSubmissionModelParams is parameters of updateSubmissionModel operation.
|
// UpdateSubmissionValidatedModelParams is parameters of updateSubmissionValidatedModel operation.
|
||||||
type UpdateSubmissionModelParams struct {
|
type UpdateSubmissionValidatedModelParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ModelID int64
|
ValidatedModelID int64
|
||||||
VersionID int64
|
ValidatedModelVersion int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackUpdateSubmissionModelParams(packed middleware.Parameters) (params UpdateSubmissionModelParams) {
|
func unpackUpdateSubmissionValidatedModelParams(packed middleware.Parameters) (params UpdateSubmissionValidatedModelParams) {
|
||||||
{
|
{
|
||||||
key := middleware.ParameterKey{
|
key := middleware.ParameterKey{
|
||||||
Name: "SubmissionID",
|
Name: "SubmissionID",
|
||||||
@@ -1134,22 +1122,22 @@ func unpackUpdateSubmissionModelParams(packed middleware.Parameters) (params Upd
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
key := middleware.ParameterKey{
|
key := middleware.ParameterKey{
|
||||||
Name: "ModelID",
|
Name: "ValidatedModelID",
|
||||||
In: "query",
|
In: "query",
|
||||||
}
|
}
|
||||||
params.ModelID = packed[key].(int64)
|
params.ValidatedModelID = packed[key].(int64)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
key := middleware.ParameterKey{
|
key := middleware.ParameterKey{
|
||||||
Name: "VersionID",
|
Name: "ValidatedModelVersion",
|
||||||
In: "query",
|
In: "query",
|
||||||
}
|
}
|
||||||
params.VersionID = packed[key].(int64)
|
params.ValidatedModelVersion = packed[key].(int64)
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeUpdateSubmissionModelParams(args [1]string, argsEscaped bool, r *http.Request) (params UpdateSubmissionModelParams, _ error) {
|
func decodeUpdateSubmissionValidatedModelParams(args [1]string, argsEscaped bool, r *http.Request) (params UpdateSubmissionValidatedModelParams, _ error) {
|
||||||
q := uri.NewQueryDecoder(r.URL.Query())
|
q := uri.NewQueryDecoder(r.URL.Query())
|
||||||
// Decode path: SubmissionID.
|
// Decode path: SubmissionID.
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
@@ -1196,10 +1184,10 @@ func decodeUpdateSubmissionModelParams(args [1]string, argsEscaped bool, r *http
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decode query: ModelID.
|
// Decode query: ValidatedModelID.
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
cfg := uri.QueryParameterDecodingConfig{
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
Name: "ModelID",
|
Name: "ValidatedModelID",
|
||||||
Style: uri.QueryStyleForm,
|
Style: uri.QueryStyleForm,
|
||||||
Explode: true,
|
Explode: true,
|
||||||
}
|
}
|
||||||
@@ -1216,26 +1204,26 @@ func decodeUpdateSubmissionModelParams(args [1]string, argsEscaped bool, r *http
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
params.ModelID = c
|
params.ValidatedModelID = c
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return params, &ogenerrors.DecodeParamError{
|
return params, &ogenerrors.DecodeParamError{
|
||||||
Name: "ModelID",
|
Name: "ValidatedModelID",
|
||||||
In: "query",
|
In: "query",
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decode query: VersionID.
|
// Decode query: ValidatedModelVersion.
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
cfg := uri.QueryParameterDecodingConfig{
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
Name: "VersionID",
|
Name: "ValidatedModelVersion",
|
||||||
Style: uri.QueryStyleForm,
|
Style: uri.QueryStyleForm,
|
||||||
Explode: true,
|
Explode: true,
|
||||||
}
|
}
|
||||||
@@ -1252,18 +1240,18 @@ func decodeUpdateSubmissionModelParams(args [1]string, argsEscaped bool, r *http
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
params.VersionID = c
|
params.ValidatedModelVersion = c
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return validate.ErrFieldRequired
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return params, &ogenerrors.DecodeParamError{
|
return params, &ogenerrors.DecodeParamError{
|
||||||
Name: "VersionID",
|
Name: "ValidatedModelVersion",
|
||||||
In: "query",
|
In: "query",
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,57 +66,6 @@ func decodeActionSubmissionAcceptedResponse(resp *http.Response) (res *ActionSub
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeActionSubmissionReleasedResponse(resp *http.Response) (res *ActionSubmissionReleasedNoContent, _ error) {
|
|
||||||
switch resp.StatusCode {
|
|
||||||
case 204:
|
|
||||||
// Code 204.
|
|
||||||
return &ActionSubmissionReleasedNoContent{}, nil
|
|
||||||
}
|
|
||||||
// Convenient error response.
|
|
||||||
defRes, err := func() (res *ErrorStatusCode, err error) {
|
|
||||||
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "parse media type")
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case ct == "application/json":
|
|
||||||
buf, err := io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
d := jx.DecodeBytes(buf)
|
|
||||||
|
|
||||||
var response Error
|
|
||||||
if err := func() error {
|
|
||||||
if err := response.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 res, err
|
|
||||||
}
|
|
||||||
return &ErrorStatusCode{
|
|
||||||
StatusCode: resp.StatusCode,
|
|
||||||
Response: response,
|
|
||||||
}, nil
|
|
||||||
default:
|
|
||||||
return res, validate.InvalidContentType(ct)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
|
|
||||||
}
|
|
||||||
return res, errors.Wrap(defRes, "error")
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeActionSubmissionUploadedResponse(resp *http.Response) (res *ActionSubmissionUploadedNoContent, _ error) {
|
func decodeActionSubmissionUploadedResponse(resp *http.Response) (res *ActionSubmissionUploadedNoContent, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 204:
|
case 204:
|
||||||
@@ -711,11 +660,11 @@ func decodeListScriptsResponse(resp *http.Response) (res []Script, _ error) {
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeUpdateSubmissionModelResponse(resp *http.Response) (res *UpdateSubmissionModelNoContent, _ error) {
|
func decodeUpdateSubmissionValidatedModelResponse(resp *http.Response) (res *UpdateSubmissionValidatedModelNoContent, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 204:
|
case 204:
|
||||||
// Code 204.
|
// Code 204.
|
||||||
return &UpdateSubmissionModelNoContent{}, nil
|
return &UpdateSubmissionValidatedModelNoContent{}, nil
|
||||||
}
|
}
|
||||||
// Convenient error response.
|
// Convenient error response.
|
||||||
defRes, err := func() (res *ErrorStatusCode, err error) {
|
defRes, err := func() (res *ErrorStatusCode, err error) {
|
||||||
|
|||||||
@@ -20,13 +20,6 @@ func encodeActionSubmissionAcceptedResponse(response *ActionSubmissionAcceptedNo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeActionSubmissionReleasedResponse(response *ActionSubmissionReleasedNoContent, 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 {
|
func encodeActionSubmissionUploadedResponse(response *ActionSubmissionUploadedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.WriteHeader(204)
|
w.WriteHeader(204)
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
@@ -119,7 +112,7 @@ func encodeListScriptsResponse(response []Script, w http.ResponseWriter, span tr
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeUpdateSubmissionModelResponse(response *UpdateSubmissionModelNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeUpdateSubmissionValidatedModelResponse(response *UpdateSubmissionValidatedModelNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.WriteHeader(204)
|
w.WriteHeader(204)
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case '/': // Prefix: "/s"
|
case '/': // Prefix: "/s"
|
||||||
origElem := elem
|
|
||||||
if l := len("/s"); len(elem) >= l && elem[0:l] == "/s" {
|
if l := len("/s"); len(elem) >= l && elem[0:l] == "/s" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -62,7 +62,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'c': // Prefix: "cript"
|
case 'c': // Prefix: "cript"
|
||||||
origElem := elem
|
|
||||||
if l := len("cript"); len(elem) >= l && elem[0:l] == "cript" {
|
if l := len("cript"); len(elem) >= l && elem[0:l] == "cript" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -74,7 +74,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case '-': // Prefix: "-policy"
|
case '-': // Prefix: "-policy"
|
||||||
origElem := elem
|
|
||||||
if l := len("-policy"); len(elem) >= l && elem[0:l] == "-policy" {
|
if l := len("-policy"); len(elem) >= l && elem[0:l] == "-policy" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -95,9 +95,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 's': // Prefix: "s"
|
case 's': // Prefix: "s"
|
||||||
origElem := elem
|
|
||||||
if l := len("s"); len(elem) >= l && elem[0:l] == "s" {
|
if l := len("s"); len(elem) >= l && elem[0:l] == "s" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -118,7 +117,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case '/': // Prefix: "/"
|
case '/': // Prefix: "/"
|
||||||
origElem := elem
|
|
||||||
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
|
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -126,7 +125,11 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Param: "ScriptID"
|
// Param: "ScriptID"
|
||||||
// Leaf parameter
|
// Leaf parameter, slashes are prohibited
|
||||||
|
idx := strings.IndexByte(elem, '/')
|
||||||
|
if idx >= 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
args[0] = elem
|
args[0] = elem
|
||||||
elem = ""
|
elem = ""
|
||||||
|
|
||||||
@@ -144,15 +147,12 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 'u': // Prefix: "ubmissions/"
|
case 'u': // Prefix: "ubmissions/"
|
||||||
origElem := elem
|
|
||||||
if l := len("ubmissions/"); len(elem) >= l && elem[0:l] == "ubmissions/" {
|
if l := len("ubmissions/"); len(elem) >= l && elem[0:l] == "ubmissions/" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -173,7 +173,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case '/': // Prefix: "/"
|
case '/': // Prefix: "/"
|
||||||
origElem := elem
|
|
||||||
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
|
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -184,32 +184,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'm': // Prefix: "model"
|
case 's': // Prefix: "status/validator-"
|
||||||
origElem := elem
|
|
||||||
if l := len("model"); len(elem) >= l && elem[0:l] == "model" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
|
||||||
case "POST":
|
|
||||||
s.handleUpdateSubmissionModelRequest([1]string{
|
|
||||||
args[0],
|
|
||||||
}, elemIsEscaped, w, r)
|
|
||||||
default:
|
|
||||||
s.notAllowed(w, r, "POST")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 's': // Prefix: "status/"
|
|
||||||
origElem := elem
|
|
||||||
if l := len("status/"); len(elem) >= l && elem[0:l] == "status/" {
|
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
@@ -219,9 +196,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'r': // Prefix: "releaser-released"
|
case 'f': // Prefix: "failed"
|
||||||
origElem := elem
|
|
||||||
if l := len("releaser-released"); len(elem) >= l && elem[0:l] == "releaser-released" {
|
if l := len("failed"); len(elem) >= l && elem[0:l] == "failed" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
@@ -231,7 +208,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// Leaf node.
|
// Leaf node.
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "POST":
|
case "POST":
|
||||||
s.handleActionSubmissionReleasedRequest([1]string{
|
s.handleActionSubmissionAcceptedRequest([1]string{
|
||||||
args[0],
|
args[0],
|
||||||
}, elemIsEscaped, w, r)
|
}, elemIsEscaped, w, r)
|
||||||
default:
|
default:
|
||||||
@@ -241,103 +218,80 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
case 'u': // Prefix: "uploaded"
|
||||||
case 'v': // Prefix: "validator-"
|
|
||||||
origElem := elem
|
if l := len("uploaded"); len(elem) >= l && elem[0:l] == "uploaded" {
|
||||||
if l := len("validator-"); len(elem) >= l && elem[0:l] == "validator-" {
|
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "POST":
|
||||||
|
s.handleActionSubmissionUploadedRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'v': // Prefix: "validated"
|
||||||
|
|
||||||
|
if l := len("validated"); len(elem) >= l && elem[0:l] == "validated" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
|
||||||
case 'f': // Prefix: "failed"
|
if len(elem) == 0 {
|
||||||
origElem := elem
|
// Leaf node.
|
||||||
if l := len("failed"); len(elem) >= l && elem[0:l] == "failed" {
|
switch r.Method {
|
||||||
elem = elem[l:]
|
case "POST":
|
||||||
} else {
|
s.handleActionSubmissionValidatedRequest([1]string{
|
||||||
break
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(elem) == 0 {
|
return
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
|
||||||
case "POST":
|
|
||||||
s.handleActionSubmissionAcceptedRequest([1]string{
|
|
||||||
args[0],
|
|
||||||
}, elemIsEscaped, w, r)
|
|
||||||
default:
|
|
||||||
s.notAllowed(w, r, "POST")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 'u': // Prefix: "uploaded"
|
|
||||||
origElem := elem
|
|
||||||
if l := len("uploaded"); len(elem) >= l && elem[0:l] == "uploaded" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
|
||||||
case "POST":
|
|
||||||
s.handleActionSubmissionUploadedRequest([1]string{
|
|
||||||
args[0],
|
|
||||||
}, elemIsEscaped, w, r)
|
|
||||||
default:
|
|
||||||
s.notAllowed(w, r, "POST")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 'v': // Prefix: "validated"
|
|
||||||
origElem := elem
|
|
||||||
if l := len("validated"); len(elem) >= l && elem[0:l] == "validated" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
|
||||||
case "POST":
|
|
||||||
s.handleActionSubmissionValidatedRequest([1]string{
|
|
||||||
args[0],
|
|
||||||
}, elemIsEscaped, w, r)
|
|
||||||
default:
|
|
||||||
s.notAllowed(w, r, "POST")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
case 'v': // Prefix: "validated-model"
|
||||||
|
|
||||||
|
if l := len("validated-model"); len(elem) >= l && elem[0:l] == "validated-model" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "POST":
|
||||||
|
s.handleUpdateSubmissionValidatedModelRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.notFound(w, r)
|
s.notFound(w, r)
|
||||||
@@ -419,7 +373,7 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case '/': // Prefix: "/s"
|
case '/': // Prefix: "/s"
|
||||||
origElem := elem
|
|
||||||
if l := len("/s"); len(elem) >= l && elem[0:l] == "/s" {
|
if l := len("/s"); len(elem) >= l && elem[0:l] == "/s" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -431,7 +385,7 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'c': // Prefix: "cript"
|
case 'c': // Prefix: "cript"
|
||||||
origElem := elem
|
|
||||||
if l := len("cript"); len(elem) >= l && elem[0:l] == "cript" {
|
if l := len("cript"); len(elem) >= l && elem[0:l] == "cript" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -443,7 +397,7 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case '-': // Prefix: "-policy"
|
case '-': // Prefix: "-policy"
|
||||||
origElem := elem
|
|
||||||
if l := len("-policy"); len(elem) >= l && elem[0:l] == "-policy" {
|
if l := len("-policy"); len(elem) >= l && elem[0:l] == "-policy" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -474,9 +428,8 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 's': // Prefix: "s"
|
case 's': // Prefix: "s"
|
||||||
origElem := elem
|
|
||||||
if l := len("s"); len(elem) >= l && elem[0:l] == "s" {
|
if l := len("s"); len(elem) >= l && elem[0:l] == "s" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -507,7 +460,7 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case '/': // Prefix: "/"
|
case '/': // Prefix: "/"
|
||||||
origElem := elem
|
|
||||||
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
|
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -515,7 +468,11 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Param: "ScriptID"
|
// Param: "ScriptID"
|
||||||
// Leaf parameter
|
// Leaf parameter, slashes are prohibited
|
||||||
|
idx := strings.IndexByte(elem, '/')
|
||||||
|
if idx >= 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
args[0] = elem
|
args[0] = elem
|
||||||
elem = ""
|
elem = ""
|
||||||
|
|
||||||
@@ -535,15 +492,12 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 'u': // Prefix: "ubmissions/"
|
case 'u': // Prefix: "ubmissions/"
|
||||||
origElem := elem
|
|
||||||
if l := len("ubmissions/"); len(elem) >= l && elem[0:l] == "ubmissions/" {
|
if l := len("ubmissions/"); len(elem) >= l && elem[0:l] == "ubmissions/" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -564,7 +518,7 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case '/': // Prefix: "/"
|
case '/': // Prefix: "/"
|
||||||
origElem := elem
|
|
||||||
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
|
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
@@ -575,34 +529,9 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'm': // Prefix: "model"
|
case 's': // Prefix: "status/validator-"
|
||||||
origElem := elem
|
|
||||||
if l := len("model"); len(elem) >= l && elem[0:l] == "model" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
||||||
// Leaf node.
|
|
||||||
switch method {
|
|
||||||
case "POST":
|
|
||||||
r.name = UpdateSubmissionModelOperation
|
|
||||||
r.summary = "Update model following role restrictions"
|
|
||||||
r.operationID = "updateSubmissionModel"
|
|
||||||
r.pathPattern = "/submissions/{SubmissionID}/model"
|
|
||||||
r.args = args
|
|
||||||
r.count = 1
|
|
||||||
return r, true
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 's': // Prefix: "status/"
|
|
||||||
origElem := elem
|
|
||||||
if l := len("status/"); len(elem) >= l && elem[0:l] == "status/" {
|
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
@@ -612,9 +541,9 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'r': // Prefix: "releaser-released"
|
case 'f': // Prefix: "failed"
|
||||||
origElem := elem
|
|
||||||
if l := len("releaser-released"); len(elem) >= l && elem[0:l] == "releaser-released" {
|
if l := len("failed"); len(elem) >= l && elem[0:l] == "failed" {
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
@@ -624,10 +553,10 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
// Leaf node.
|
// Leaf node.
|
||||||
switch method {
|
switch method {
|
||||||
case "POST":
|
case "POST":
|
||||||
r.name = ActionSubmissionReleasedOperation
|
r.name = ActionSubmissionAcceptedOperation
|
||||||
r.summary = "(Internal endpoint) Role Releaser changes status from releasing -> released"
|
r.summary = "(Internal endpoint) Role Validator changes status from Validating -> Accepted"
|
||||||
r.operationID = "actionSubmissionReleased"
|
r.operationID = "actionSubmissionAccepted"
|
||||||
r.pathPattern = "/submissions/{SubmissionID}/status/releaser-released"
|
r.pathPattern = "/submissions/{SubmissionID}/status/validator-failed"
|
||||||
r.args = args
|
r.args = args
|
||||||
r.count = 1
|
r.count = 1
|
||||||
return r, true
|
return r, true
|
||||||
@@ -636,109 +565,86 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
case 'u': // Prefix: "uploaded"
|
||||||
case 'v': // Prefix: "validator-"
|
|
||||||
origElem := elem
|
if l := len("uploaded"); len(elem) >= l && elem[0:l] == "uploaded" {
|
||||||
if l := len("validator-"); len(elem) >= l && elem[0:l] == "validator-" {
|
|
||||||
elem = elem[l:]
|
elem = elem[l:]
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "POST":
|
||||||
|
r.name = ActionSubmissionUploadedOperation
|
||||||
|
r.summary = "(Internal endpoint) Role Validator changes status from Uploading -> Uploaded"
|
||||||
|
r.operationID = "actionSubmissionUploaded"
|
||||||
|
r.pathPattern = "/submissions/{SubmissionID}/status/validator-uploaded"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'v': // Prefix: "validated"
|
||||||
|
|
||||||
|
if l := len("validated"); len(elem) >= l && elem[0:l] == "validated" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
|
||||||
case 'f': // Prefix: "failed"
|
|
||||||
origElem := elem
|
|
||||||
if l := len("failed"); len(elem) >= l && elem[0:l] == "failed" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
// Leaf node.
|
// Leaf node.
|
||||||
switch method {
|
switch method {
|
||||||
case "POST":
|
case "POST":
|
||||||
r.name = ActionSubmissionAcceptedOperation
|
r.name = ActionSubmissionValidatedOperation
|
||||||
r.summary = "(Internal endpoint) Role Validator changes status from Validating -> Accepted"
|
r.summary = "(Internal endpoint) Role Validator changes status from Validating -> Validated"
|
||||||
r.operationID = "actionSubmissionAccepted"
|
r.operationID = "actionSubmissionValidated"
|
||||||
r.pathPattern = "/submissions/{SubmissionID}/status/validator-failed"
|
r.pathPattern = "/submissions/{SubmissionID}/status/validator-validated"
|
||||||
r.args = args
|
r.args = args
|
||||||
r.count = 1
|
r.count = 1
|
||||||
return r, true
|
return r, true
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 'u': // Prefix: "uploaded"
|
|
||||||
origElem := elem
|
|
||||||
if l := len("uploaded"); len(elem) >= l && elem[0:l] == "uploaded" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
|
||||||
// Leaf node.
|
|
||||||
switch method {
|
|
||||||
case "POST":
|
|
||||||
r.name = ActionSubmissionUploadedOperation
|
|
||||||
r.summary = "(Internal endpoint) Role Validator changes status from Uploading -> Uploaded"
|
|
||||||
r.operationID = "actionSubmissionUploaded"
|
|
||||||
r.pathPattern = "/submissions/{SubmissionID}/status/validator-uploaded"
|
|
||||||
r.args = args
|
|
||||||
r.count = 1
|
|
||||||
return r, true
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
case 'v': // Prefix: "validated"
|
|
||||||
origElem := elem
|
|
||||||
if l := len("validated"); len(elem) >= l && elem[0:l] == "validated" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
|
||||||
// Leaf node.
|
|
||||||
switch method {
|
|
||||||
case "POST":
|
|
||||||
r.name = ActionSubmissionValidatedOperation
|
|
||||||
r.summary = "(Internal endpoint) Role Validator changes status from Validating -> Validated"
|
|
||||||
r.operationID = "actionSubmissionValidated"
|
|
||||||
r.pathPattern = "/submissions/{SubmissionID}/status/validator-validated"
|
|
||||||
r.args = args
|
|
||||||
r.count = 1
|
|
||||||
return r, true
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
case 'v': // Prefix: "validated-model"
|
||||||
|
|
||||||
|
if l := len("validated-model"); len(elem) >= l && elem[0:l] == "validated-model" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "POST":
|
||||||
|
r.name = UpdateSubmissionValidatedModelOperation
|
||||||
|
r.summary = "Update validated model"
|
||||||
|
r.operationID = "updateSubmissionValidatedModel"
|
||||||
|
r.pathPattern = "/submissions/{SubmissionID}/validated-model"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = origElem
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r, false
|
return r, false
|
||||||
|
|||||||
@@ -13,9 +13,6 @@ func (s *ErrorStatusCode) Error() string {
|
|||||||
// ActionSubmissionAcceptedNoContent is response for ActionSubmissionAccepted operation.
|
// ActionSubmissionAcceptedNoContent is response for ActionSubmissionAccepted operation.
|
||||||
type ActionSubmissionAcceptedNoContent struct{}
|
type ActionSubmissionAcceptedNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionReleasedNoContent is response for ActionSubmissionReleased operation.
|
|
||||||
type ActionSubmissionReleasedNoContent struct{}
|
|
||||||
|
|
||||||
// ActionSubmissionUploadedNoContent is response for ActionSubmissionUploaded operation.
|
// ActionSubmissionUploadedNoContent is response for ActionSubmissionUploaded operation.
|
||||||
type ActionSubmissionUploadedNoContent struct{}
|
type ActionSubmissionUploadedNoContent struct{}
|
||||||
|
|
||||||
@@ -234,7 +231,8 @@ type Script struct {
|
|||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
Hash string `json:"Hash"`
|
Hash string `json:"Hash"`
|
||||||
Source string `json:"Source"`
|
Source string `json:"Source"`
|
||||||
SubmissionID int64 `json:"SubmissionID"`
|
ResourceType int32 `json:"ResourceType"`
|
||||||
|
ResourceID int64 `json:"ResourceID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID returns the value of ID.
|
// GetID returns the value of ID.
|
||||||
@@ -257,9 +255,14 @@ func (s *Script) GetSource() string {
|
|||||||
return s.Source
|
return s.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubmissionID returns the value of SubmissionID.
|
// GetResourceType returns the value of ResourceType.
|
||||||
func (s *Script) GetSubmissionID() int64 {
|
func (s *Script) GetResourceType() int32 {
|
||||||
return s.SubmissionID
|
return s.ResourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceID returns the value of ResourceID.
|
||||||
|
func (s *Script) GetResourceID() int64 {
|
||||||
|
return s.ResourceID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetID sets the value of ID.
|
// SetID sets the value of ID.
|
||||||
@@ -282,16 +285,22 @@ func (s *Script) SetSource(val string) {
|
|||||||
s.Source = val
|
s.Source = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSubmissionID sets the value of SubmissionID.
|
// SetResourceType sets the value of ResourceType.
|
||||||
func (s *Script) SetSubmissionID(val int64) {
|
func (s *Script) SetResourceType(val int32) {
|
||||||
s.SubmissionID = val
|
s.ResourceType = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceID sets the value of ResourceID.
|
||||||
|
func (s *Script) SetResourceID(val int64) {
|
||||||
|
s.ResourceID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/ScriptCreate
|
// Ref: #/components/schemas/ScriptCreate
|
||||||
type ScriptCreate struct {
|
type ScriptCreate struct {
|
||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
Source string `json:"Source"`
|
Source string `json:"Source"`
|
||||||
SubmissionID OptInt64 `json:"SubmissionID"`
|
ResourceType int32 `json:"ResourceType"`
|
||||||
|
ResourceID OptInt64 `json:"ResourceID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetName returns the value of Name.
|
// GetName returns the value of Name.
|
||||||
@@ -304,9 +313,14 @@ func (s *ScriptCreate) GetSource() string {
|
|||||||
return s.Source
|
return s.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSubmissionID returns the value of SubmissionID.
|
// GetResourceType returns the value of ResourceType.
|
||||||
func (s *ScriptCreate) GetSubmissionID() OptInt64 {
|
func (s *ScriptCreate) GetResourceType() int32 {
|
||||||
return s.SubmissionID
|
return s.ResourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceID returns the value of ResourceID.
|
||||||
|
func (s *ScriptCreate) GetResourceID() OptInt64 {
|
||||||
|
return s.ResourceID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetName sets the value of Name.
|
// SetName sets the value of Name.
|
||||||
@@ -319,9 +333,14 @@ func (s *ScriptCreate) SetSource(val string) {
|
|||||||
s.Source = val
|
s.Source = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSubmissionID sets the value of SubmissionID.
|
// SetResourceType sets the value of ResourceType.
|
||||||
func (s *ScriptCreate) SetSubmissionID(val OptInt64) {
|
func (s *ScriptCreate) SetResourceType(val int32) {
|
||||||
s.SubmissionID = val
|
s.ResourceType = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceID sets the value of ResourceID.
|
||||||
|
func (s *ScriptCreate) SetResourceID(val OptInt64) {
|
||||||
|
s.ResourceID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/ScriptPolicy
|
// Ref: #/components/schemas/ScriptPolicy
|
||||||
@@ -409,5 +428,5 @@ func (s *ScriptPolicyCreate) SetPolicy(val int32) {
|
|||||||
s.Policy = val
|
s.Policy = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSubmissionModelNoContent is response for UpdateSubmissionModel operation.
|
// UpdateSubmissionValidatedModelNoContent is response for UpdateSubmissionValidatedModel operation.
|
||||||
type UpdateSubmissionModelNoContent struct{}
|
type UpdateSubmissionValidatedModelNoContent struct{}
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/validator-failed
|
// POST /submissions/{SubmissionID}/status/validator-failed
|
||||||
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
||||||
// ActionSubmissionReleased implements actionSubmissionReleased operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Releaser changes status from releasing -> released.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/releaser-released
|
|
||||||
ActionSubmissionReleased(ctx context.Context, params ActionSubmissionReleasedParams) error
|
|
||||||
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
||||||
//
|
//
|
||||||
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
@@ -62,12 +56,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// GET /scripts
|
// GET /scripts
|
||||||
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
|
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
|
||||||
// UpdateSubmissionModel implements updateSubmissionModel operation.
|
// UpdateSubmissionValidatedModel implements updateSubmissionValidatedModel operation.
|
||||||
//
|
//
|
||||||
// Update model following role restrictions.
|
// Update validated model.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/model
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
UpdateSubmissionModel(ctx context.Context, params UpdateSubmissionModelParams) error
|
UpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) error
|
||||||
// NewError creates *ErrorStatusCode from error returned by handler.
|
// NewError creates *ErrorStatusCode from error returned by handler.
|
||||||
//
|
//
|
||||||
// Used for common default response.
|
// Used for common default response.
|
||||||
|
|||||||
@@ -22,15 +22,6 @@ func (UnimplementedHandler) ActionSubmissionAccepted(ctx context.Context, params
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionReleased implements actionSubmissionReleased operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Releaser changes status from releasing -> released.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/releaser-released
|
|
||||||
func (UnimplementedHandler) ActionSubmissionReleased(ctx context.Context, params ActionSubmissionReleasedParams) error {
|
|
||||||
return ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
||||||
//
|
//
|
||||||
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
@@ -94,12 +85,12 @@ func (UnimplementedHandler) ListScripts(ctx context.Context, params ListScriptsP
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSubmissionModel implements updateSubmissionModel operation.
|
// UpdateSubmissionValidatedModel implements updateSubmissionValidatedModel operation.
|
||||||
//
|
//
|
||||||
// Update model following role restrictions.
|
// Update validated model.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/model
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
func (UnimplementedHandler) UpdateSubmissionModel(ctx context.Context, params UpdateSubmissionModelParams) error {
|
func (UnimplementedHandler) UpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) error {
|
||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,18 +10,18 @@ type ValidateRequest struct {
|
|||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ModelID int64
|
ModelID int64
|
||||||
ModelVersion int64
|
ModelVersion int64
|
||||||
ValidatedModelID int64 // optional value
|
ValidatedModelID *int64 // optional value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new map
|
// Create a new map
|
||||||
type PublishNewRequest struct {
|
type UploadNewRequest struct {
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ModelID int64
|
ModelID int64
|
||||||
ModelVersion int64
|
ModelVersion int64
|
||||||
ModelName string
|
ModelName string
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublishFixRequest struct {
|
type UploadFixRequest struct {
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ModelID int64
|
ModelID int64
|
||||||
ModelVersion int64
|
ModelVersion int64
|
||||||
|
|||||||
@@ -23,12 +23,20 @@ func HashParse(hash string) (uint64, error){
|
|||||||
return strconv.ParseUint(hash, 16, 64)
|
return strconv.ParseUint(hash, 16, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResourceType int32
|
||||||
|
const (
|
||||||
|
ResourceUnknown ResourceType = 0
|
||||||
|
ResourceMapfix ResourceType = 1
|
||||||
|
ResourceSubmission ResourceType = 2
|
||||||
|
)
|
||||||
|
|
||||||
type Script struct {
|
type Script struct {
|
||||||
ID int64 `gorm:"primaryKey"`
|
ID int64 `gorm:"primaryKey"`
|
||||||
Name string
|
Name string
|
||||||
Hash int64 // postgres does not support unsigned integers, so we have to pretend
|
Hash int64 // postgres does not support unsigned integers, so we have to pretend
|
||||||
Source string
|
Source string
|
||||||
SubmissionID int64 // which submission did this script first appear in
|
ResourceType ResourceType // is this a submission or is it a mapfix
|
||||||
|
ResourceID int64 // which submission / mapfix did this script first appear in
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,24 +2,24 @@ package model
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Status int32
|
type SubmissionStatus int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Phase: Final Status
|
// Phase: Final SubmissionStatus
|
||||||
StatusReleased Status = 9
|
SubmissionStatusReleased SubmissionStatus = 9
|
||||||
StatusRejected Status = 8
|
SubmissionStatusRejected SubmissionStatus = 8
|
||||||
|
|
||||||
// Phase: Testing
|
// Phase: Testing
|
||||||
StatusUploaded Status = 7 // uploaded to the group, but pending release
|
SubmissionStatusUploaded SubmissionStatus = 7 // uploaded to the group, but pending release
|
||||||
StatusUploading Status = 6
|
SubmissionStatusUploading SubmissionStatus = 6
|
||||||
StatusValidated Status = 5
|
SubmissionStatusValidated SubmissionStatus = 5
|
||||||
StatusValidating Status = 4
|
SubmissionStatusValidating SubmissionStatus = 4
|
||||||
StatusAccepted Status = 3 // pending script review, can re-trigger validation
|
SubmissionStatusAccepted SubmissionStatus = 3 // pending script review, can re-trigger validation
|
||||||
|
|
||||||
// Phase: Creation
|
// Phase: Creation
|
||||||
StatusChangesRequested Status = 2
|
SubmissionStatusChangesRequested SubmissionStatus = 2
|
||||||
StatusSubmitted Status = 1
|
SubmissionStatusSubmitted SubmissionStatus = 1
|
||||||
StatusUnderConstruction Status = 0
|
SubmissionStatusUnderConstruction SubmissionStatus = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
type Submission struct {
|
type Submission struct {
|
||||||
@@ -32,7 +32,10 @@ type Submission struct {
|
|||||||
Submitter int64 // UserID
|
Submitter int64 // UserID
|
||||||
AssetID int64
|
AssetID int64
|
||||||
AssetVersion int64
|
AssetVersion int64
|
||||||
|
ValidatedAssetID int64
|
||||||
|
ValidatedAssetVersion int64
|
||||||
Completed bool // Has this version of the map been completed at least once on maptest
|
Completed bool // Has this version of the map been completed at least once on maptest
|
||||||
TargetAssetID int64 // where to upload map fix. if the TargetAssetID is 0, it's a new map.
|
UploadedAssetID int64 // where to upload map fix. if the TargetAssetID is 0, it's a new map.
|
||||||
StatusID Status
|
StatusID SubmissionStatus
|
||||||
|
StatusMessage string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
//
|
//
|
||||||
// POST /script-policy
|
// POST /script-policy
|
||||||
func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolicyCreate) (*api.ID, error) {
|
func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolicyCreate) (*api.ID, error) {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrUserInfo
|
return nil, ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -81,12 +81,12 @@ func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptP
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resp []api.ScriptPolicy
|
var resp []api.ScriptPolicy
|
||||||
for i := 0; i < len(items); i++ {
|
for _, item := range items {
|
||||||
resp = append(resp, api.ScriptPolicy{
|
resp = append(resp, api.ScriptPolicy{
|
||||||
ID: items[i].ID,
|
ID: item.ID,
|
||||||
FromScriptHash: model.HashFormat(uint64(items[i].FromScriptHash)),
|
FromScriptHash: model.HashFormat(uint64(item.FromScriptHash)),
|
||||||
ToScriptID: items[i].ToScriptID,
|
ToScriptID: item.ToScriptID,
|
||||||
Policy: int32(items[i].Policy),
|
Policy: int32(item.Policy),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptP
|
|||||||
//
|
//
|
||||||
// DELETE /script-policy/{ScriptPolicyID}
|
// DELETE /script-policy/{ScriptPolicyID}
|
||||||
func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScriptPolicyParams) error {
|
func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScriptPolicyParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScr
|
|||||||
//
|
//
|
||||||
// GET /script-policy/{ScriptPolicyID}
|
// GET /script-policy/{ScriptPolicyID}
|
||||||
func (svc *Service) GetScriptPolicy(ctx context.Context, params api.GetScriptPolicyParams) (*api.ScriptPolicy, error) {
|
func (svc *Service) GetScriptPolicy(ctx context.Context, params api.GetScriptPolicyParams) (*api.ScriptPolicy, error) {
|
||||||
_, ok := ctx.Value("UserInfo").(UserInfo)
|
_, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrUserInfo
|
return nil, ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ func (svc *Service) GetScriptPolicy(ctx context.Context, params api.GetScriptPol
|
|||||||
//
|
//
|
||||||
// POST /script-policy/{ScriptPolicyID}
|
// POST /script-policy/{ScriptPolicyID}
|
||||||
func (svc *Service) UpdateScriptPolicy(ctx context.Context, req *api.ScriptPolicyUpdate, params api.UpdateScriptPolicyParams) error {
|
func (svc *Service) UpdateScriptPolicy(ctx context.Context, req *api.ScriptPolicyUpdate, params api.UpdateScriptPolicyParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
//
|
//
|
||||||
// POST /scripts
|
// POST /scripts
|
||||||
func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*api.ID, error) {
|
func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*api.ID, error) {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrUserInfo
|
return nil, ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,8 @@ func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*a
|
|||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
Hash: int64(model.HashSource(req.Source)),
|
Hash: int64(model.HashSource(req.Source)),
|
||||||
Source: req.Source,
|
Source: req.Source,
|
||||||
SubmissionID: req.SubmissionID.Or(0),
|
ResourceType: model.ResourceType(req.ResourceType),
|
||||||
|
ResourceID: req.ResourceID.Or(0),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -77,12 +78,13 @@ func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParam
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resp []api.Script
|
var resp []api.Script
|
||||||
for i := 0; i < len(items); i++ {
|
for _, item := range items {
|
||||||
resp = append(resp, api.Script{
|
resp = append(resp, api.Script{
|
||||||
ID: items[i].ID,
|
ID: item.ID,
|
||||||
Hash: model.HashFormat(uint64(items[i].Hash)),
|
Hash: model.HashFormat(uint64(item.Hash)),
|
||||||
Source: items[i].Source,
|
Source: item.Source,
|
||||||
SubmissionID: items[i].SubmissionID,
|
ResourceType: int32(item.ResourceType),
|
||||||
|
ResourceID: item.ResourceID,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +97,7 @@ func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParam
|
|||||||
//
|
//
|
||||||
// DELETE /scripts/{ScriptID}
|
// DELETE /scripts/{ScriptID}
|
||||||
func (svc *Service) DeleteScript(ctx context.Context, params api.DeleteScriptParams) error {
|
func (svc *Service) DeleteScript(ctx context.Context, params api.DeleteScriptParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -117,7 +119,7 @@ func (svc *Service) DeleteScript(ctx context.Context, params api.DeleteScriptPar
|
|||||||
//
|
//
|
||||||
// GET /scripts/{ScriptID}
|
// GET /scripts/{ScriptID}
|
||||||
func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (*api.Script, error) {
|
func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (*api.Script, error) {
|
||||||
_, ok := ctx.Value("UserInfo").(UserInfo)
|
_, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrUserInfo
|
return nil, ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -134,7 +136,8 @@ func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (
|
|||||||
Name: script.Name,
|
Name: script.Name,
|
||||||
Hash: model.HashFormat(uint64(script.Hash)),
|
Hash: model.HashFormat(uint64(script.Hash)),
|
||||||
Source: script.Source,
|
Source: script.Source,
|
||||||
SubmissionID: script.SubmissionID,
|
ResourceType: int32(script.ResourceType),
|
||||||
|
ResourceID: script.ResourceID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +147,7 @@ func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (
|
|||||||
//
|
//
|
||||||
// PATCH /scripts/{ScriptID}
|
// PATCH /scripts/{ScriptID}
|
||||||
func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, params api.UpdateScriptParams) error {
|
func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, params api.UpdateScriptParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -165,8 +168,11 @@ func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, par
|
|||||||
pmap.Add("source", source)
|
pmap.Add("source", source)
|
||||||
pmap.Add("hash", int64(model.HashSource(source))) // No type safety!
|
pmap.Add("hash", int64(model.HashSource(source))) // No type safety!
|
||||||
}
|
}
|
||||||
if SubmissionID, ok := req.SubmissionID.Get(); ok {
|
if ResourceType, ok := req.ResourceType.Get(); ok {
|
||||||
pmap.Add("submission_id", SubmissionID)
|
pmap.Add("resource_type", ResourceType)
|
||||||
|
}
|
||||||
|
if ResourceID, ok := req.ResourceID.Get(); ok {
|
||||||
|
pmap.Add("resource_id", ResourceID)
|
||||||
}
|
}
|
||||||
return svc.DB.Scripts().Update(ctx, req.ID, pmap)
|
return svc.DB.Scripts().Update(ctx, req.ID, pmap)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,24 +14,61 @@ var (
|
|||||||
ErrInvalidSession = errors.New("Session invalid")
|
ErrInvalidSession = errors.New("Session invalid")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Role int32
|
// Submissions roles bitflag
|
||||||
|
type Roles int32
|
||||||
var (
|
var (
|
||||||
// has ScriptWrite
|
RolesSubmissionRelease Roles = 1<<4
|
||||||
RoleQuat Role = 255
|
RolesScriptWrite Roles = 1<<3
|
||||||
// has SubmissionPublish
|
RolesMapUpload Roles = 1<<2
|
||||||
RoleMapAdmin Role = 128
|
RolesMapReview Roles = 1<<1
|
||||||
// has SubmissionReview
|
RolesMapDownload Roles = 1<<0
|
||||||
RoleMapCouncil Role = 64
|
RolesEmpty Roles = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserInfo struct {
|
// StrafesNET group roles
|
||||||
|
type GroupRole int32
|
||||||
|
var (
|
||||||
|
// has ScriptWrite
|
||||||
|
RoleQuat GroupRole = 255
|
||||||
|
RoleItzaname GroupRole = 254
|
||||||
|
RoleStagingDeveloper GroupRole = 240
|
||||||
|
RolesAll Roles = RolesScriptWrite|RolesSubmissionRelease|RolesMapUpload|RolesMapReview|RolesMapDownload
|
||||||
|
// has SubmissionUpload
|
||||||
|
RoleMapAdmin GroupRole = 128
|
||||||
|
RolesMapAdmin Roles = RolesSubmissionRelease|RolesMapUpload|RolesMapReview|RolesMapDownload
|
||||||
|
// has SubmissionReview
|
||||||
|
RoleMapCouncil GroupRole = 64
|
||||||
|
RolesMapCouncil Roles = RolesMapReview|RolesMapUpload|RolesMapDownload
|
||||||
|
// access to downloading maps
|
||||||
|
RoleMapAccess GroupRole = 32
|
||||||
|
RolesMapAccess Roles = RolesMapDownload
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserInfoHandle struct {
|
||||||
// Would love to know a better way to do this
|
// Would love to know a better way to do this
|
||||||
svc *SecurityHandler
|
svc *SecurityHandler
|
||||||
ctx *context.Context
|
ctx *context.Context
|
||||||
sessionId string
|
sessionId string
|
||||||
}
|
}
|
||||||
|
type UserInfo struct {
|
||||||
|
UserID uint64
|
||||||
|
Username string
|
||||||
|
AvatarURL string
|
||||||
|
}
|
||||||
|
|
||||||
func (usr UserInfo) GetUserID() (uint64, error) {
|
func (usr UserInfoHandle) GetUserInfo() (userInfo UserInfo, err error) {
|
||||||
|
session, err := usr.svc.Client.GetSessionUser(*usr.ctx, &auth.IdMessage{
|
||||||
|
SessionID: usr.sessionId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return userInfo, err
|
||||||
|
}
|
||||||
|
userInfo.UserID = session.UserID
|
||||||
|
userInfo.Username = session.Username
|
||||||
|
userInfo.AvatarURL = session.AvatarURL
|
||||||
|
return userInfo, nil
|
||||||
|
}
|
||||||
|
func (usr UserInfoHandle) GetUserID() (uint64, error) {
|
||||||
session, err := usr.svc.Client.GetSessionUser(*usr.ctx, &auth.IdMessage{
|
session, err := usr.svc.Client.GetSessionUser(*usr.ctx, &auth.IdMessage{
|
||||||
SessionID: usr.sessionId,
|
SessionID: usr.sessionId,
|
||||||
})
|
})
|
||||||
@@ -40,43 +77,80 @@ func (usr UserInfo) GetUserID() (uint64, error) {
|
|||||||
}
|
}
|
||||||
return session.UserID, nil
|
return session.UserID, nil
|
||||||
}
|
}
|
||||||
func (usr UserInfo) IsSubmitter(submitter uint64) (bool, error) {
|
func (usr UserInfoHandle) Validate() (bool, error) {
|
||||||
|
validate, err := usr.svc.Client.ValidateSession(*usr.ctx, &auth.IdMessage{
|
||||||
|
SessionID: usr.sessionId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return validate.Valid, nil
|
||||||
|
}
|
||||||
|
func (usr UserInfoHandle) IsSubmitter(submitter uint64) (bool, error) {
|
||||||
userId, err := usr.GetUserID()
|
userId, err := usr.GetUserID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return userId == submitter, nil
|
return userId == submitter, nil
|
||||||
}
|
}
|
||||||
func (usr UserInfo) hasRole(role Role) (bool, error) {
|
func (usr UserInfoHandle) hasRoles(wantRoles Roles) (bool, error) {
|
||||||
roles, err := usr.svc.Client.GetGroupRole(*usr.ctx, &auth.IdMessage{
|
haveroles, err := usr.GetRoles()
|
||||||
SessionID: usr.sessionId,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return haveroles & wantRoles == wantRoles, nil
|
||||||
|
}
|
||||||
|
func (usr UserInfoHandle) GetRoles() (Roles, error) {
|
||||||
|
roles, err := usr.svc.Client.GetGroupRole(*usr.ctx, &auth.IdMessage{
|
||||||
|
SessionID: usr.sessionId,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return RolesEmpty, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// map roles into bitflag
|
||||||
|
rolesBitflag := RolesEmpty;
|
||||||
for _, r := range roles.Roles {
|
for _, r := range roles.Roles {
|
||||||
if int32(role) <= r.Rank {
|
switch GroupRole(r.Rank){
|
||||||
return true, nil
|
case RoleQuat, RoleItzaname, RoleStagingDeveloper:
|
||||||
|
rolesBitflag|=RolesAll
|
||||||
|
case RoleMapAdmin:
|
||||||
|
rolesBitflag|=RolesMapAdmin
|
||||||
|
case RoleMapCouncil:
|
||||||
|
rolesBitflag|=RolesMapCouncil
|
||||||
|
case RoleMapAccess:
|
||||||
|
rolesBitflag|=RolesMapAccess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false, nil
|
return rolesBitflag, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// RoleThumbnail
|
// RoleThumbnail
|
||||||
// RoleMapDownload
|
func (usr UserInfoHandle) HasRoleMapfixUpload() (bool, error) {
|
||||||
func (usr UserInfo) HasRoleSubmissionRelease() (bool, error) {
|
return usr.hasRoles(RolesMapUpload)
|
||||||
return usr.hasRole(RoleMapAdmin)
|
|
||||||
}
|
}
|
||||||
func (usr UserInfo) HasRoleSubmissionReview() (bool, error) {
|
func (usr UserInfoHandle) HasRoleMapfixReview() (bool, error) {
|
||||||
return usr.hasRole(RoleMapCouncil)
|
return usr.hasRoles(RolesMapReview)
|
||||||
}
|
}
|
||||||
func (usr UserInfo) HasRoleScriptWrite() (bool, error) {
|
func (usr UserInfoHandle) HasRoleMapDownload() (bool, error) {
|
||||||
return usr.hasRole(RoleQuat)
|
return usr.hasRoles(RolesMapDownload)
|
||||||
|
}
|
||||||
|
func (usr UserInfoHandle) HasRoleSubmissionRelease() (bool, error) {
|
||||||
|
return usr.hasRoles(RolesSubmissionRelease)
|
||||||
|
}
|
||||||
|
func (usr UserInfoHandle) HasRoleSubmissionUpload() (bool, error) {
|
||||||
|
return usr.hasRoles(RolesMapUpload)
|
||||||
|
}
|
||||||
|
func (usr UserInfoHandle) HasRoleSubmissionReview() (bool, error) {
|
||||||
|
return usr.hasRoles(RolesMapReview)
|
||||||
|
}
|
||||||
|
func (usr UserInfoHandle) HasRoleScriptWrite() (bool, error) {
|
||||||
|
return usr.hasRoles(RolesScriptWrite)
|
||||||
}
|
}
|
||||||
/// Not implemented
|
/// Not implemented
|
||||||
func (usr UserInfo) HasRoleMaptest() (bool, error) {
|
func (usr UserInfoHandle) HasRoleMaptest() (bool, error) {
|
||||||
println("HasRoleMaptest is not implemented!")
|
println("HasRoleMaptest is not implemented!")
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@@ -91,17 +165,7 @@ func (svc SecurityHandler) HandleCookieAuth(ctx context.Context, operationName a
|
|||||||
return nil, ErrMissingSessionID
|
return nil, ErrMissingSessionID
|
||||||
}
|
}
|
||||||
|
|
||||||
validate, err := svc.Client.ValidateSession(ctx, &auth.IdMessage{
|
newCtx := context.WithValue(ctx, "UserInfo", UserInfoHandle{
|
||||||
SessionID: sessionId,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !validate.Valid {
|
|
||||||
return nil, ErrInvalidSession
|
|
||||||
}
|
|
||||||
|
|
||||||
newCtx := context.WithValue(ctx, "UserInfo", UserInfo{
|
|
||||||
svc: &svc,
|
svc: &svc,
|
||||||
ctx: &ctx,
|
ctx: &ctx,
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
@@ -13,11 +16,20 @@ var (
|
|||||||
ErrPermissionDenied = errors.New("Permission denied")
|
ErrPermissionDenied = errors.New("Permission denied")
|
||||||
// ErrUserInfo user info is missing for some reason
|
// ErrUserInfo user info is missing for some reason
|
||||||
ErrUserInfo = errors.New("Missing user info")
|
ErrUserInfo = errors.New("Missing user info")
|
||||||
|
ErrDelayReset = errors.New("Please give the validator at least 10 seconds to operate before attempting to reset the status")
|
||||||
|
ErrPermissionDeniedNotSubmitter = fmt.Errorf("%w: You must be the submitter to perform this action", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleSubmissionRelease = fmt.Errorf("%w: Need Role SubmissionRelease", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleMapUpload = fmt.Errorf("%w: Need Role MapUpload", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleMapReview = fmt.Errorf("%w: Need Role MapReview", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleMapDownload = fmt.Errorf("%w: Need Role MapDownload", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleScriptWrite = fmt.Errorf("%w: Need Role ScriptWrite", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleMaptest = fmt.Errorf("%w: Need Role Maptest", ErrPermissionDenied)
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
DB datastore.Datastore
|
DB datastore.Datastore
|
||||||
Nats nats.JetStreamContext
|
Nats nats.JetStreamContext
|
||||||
|
Client maps.MapsServiceClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewError creates *ErrorStatusCode from error returned by handler.
|
// NewError creates *ErrorStatusCode from error returned by handler.
|
||||||
|
|||||||
68
pkg/service/session.go
Normal file
68
pkg/service/session.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SessionRoles implements getSessionRoles operation.
|
||||||
|
//
|
||||||
|
// Get bitflags of permissions the currently logged in user has.
|
||||||
|
//
|
||||||
|
// GET /session/roles
|
||||||
|
func (svc *Service) SessionRoles(ctx context.Context) (*api.Roles, error) {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
roles, err := userInfo.GetRoles();
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.Roles{Roles: int32(roles)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionUser implements sessionUser operation.
|
||||||
|
//
|
||||||
|
// Get information about the currently logged in user.
|
||||||
|
//
|
||||||
|
// GET /session/roles
|
||||||
|
func (svc *Service) SessionUser(ctx context.Context) (*api.User, error) {
|
||||||
|
userInfoHandle, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
userInfo, err := userInfoHandle.GetUserInfo();
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.User{
|
||||||
|
UserID:int64(userInfo.UserID),
|
||||||
|
Username:userInfo.Username,
|
||||||
|
AvatarURL:userInfo.AvatarURL,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionUser implements sessionUser operation.
|
||||||
|
//
|
||||||
|
// Get information about the currently logged in user.
|
||||||
|
//
|
||||||
|
// GET /session/roles
|
||||||
|
func (svc *Service) SessionValidate(ctx context.Context) (bool, error) {
|
||||||
|
userInfoHandle, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return false, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
valid, err := userInfoHandle.Validate();
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid, nil
|
||||||
|
}
|
||||||
@@ -4,7 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
@@ -12,32 +15,42 @@ import (
|
|||||||
|
|
||||||
var(
|
var(
|
||||||
CreationPhaseSubmissionsLimit = 20
|
CreationPhaseSubmissionsLimit = 20
|
||||||
CreationPhaseSubmissionStatuses = []model.Status{
|
CreationPhaseSubmissionStatuses = []model.SubmissionStatus{
|
||||||
model.StatusChangesRequested,
|
model.SubmissionStatusChangesRequested,
|
||||||
model.StatusSubmitted,
|
model.SubmissionStatusSubmitted,
|
||||||
model.StatusUnderConstruction,
|
model.SubmissionStatusUnderConstruction,
|
||||||
}
|
}
|
||||||
ActiveSubmissionStatuses = []model.Status{
|
// prevent two mapfixes with same asset id
|
||||||
model.StatusUploaded,
|
ActiveSubmissionStatuses = []model.SubmissionStatus{
|
||||||
model.StatusUploading,
|
model.SubmissionStatusUploading,
|
||||||
model.StatusValidated,
|
model.SubmissionStatusValidated,
|
||||||
model.StatusValidating,
|
model.SubmissionStatusValidating,
|
||||||
model.StatusAccepted,
|
model.SubmissionStatusAccepted,
|
||||||
model.StatusChangesRequested,
|
model.SubmissionStatusChangesRequested,
|
||||||
model.StatusSubmitted,
|
model.SubmissionStatusSubmitted,
|
||||||
model.StatusUnderConstruction,
|
model.SubmissionStatusUnderConstruction,
|
||||||
|
}
|
||||||
|
// limit mapfixes in the pipeline to one per target map
|
||||||
|
ActiveAcceptedSubmissionStatuses = []model.SubmissionStatus{
|
||||||
|
model.SubmissionStatusUploading,
|
||||||
|
model.SubmissionStatusValidated,
|
||||||
|
model.SubmissionStatusValidating,
|
||||||
|
model.SubmissionStatusAccepted,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrCreationPhaseSubmissionsLimit = errors.New("Active submissions limited to 20")
|
ErrCreationPhaseSubmissionsLimit = errors.New("Active submissions limited to 20")
|
||||||
ErrActiveSubmissionSameAssetID = errors.New("There is an active submission with the same AssetID")
|
ErrActiveSubmissionSameAssetID = errors.New("There is an active submission with the same AssetID")
|
||||||
ErrActiveSubmissionSameTargetAssetID = errors.New("There is an active submission with the same TargetAssetID")
|
ErrUploadedAssetIDAlreadyExists = errors.New("The submission UploadedAssetID is already set")
|
||||||
|
ErrReleaseInvalidStatus = errors.New("Only submissions with Uploaded status can be released")
|
||||||
|
ErrReleaseNoUploadedAssetID = errors.New("Only submissions with a UploadedAssetID can be released")
|
||||||
|
ErrAcceptOwnSubmission = fmt.Errorf("%w: You cannot accept your own submission as the submitter", ErrPermissionDenied)
|
||||||
)
|
)
|
||||||
|
|
||||||
// POST /submissions
|
// POST /submissions
|
||||||
func (svc *Service) CreateSubmission(ctx context.Context, request *api.SubmissionCreate) (*api.ID, error) {
|
func (svc *Service) CreateSubmission(ctx context.Context, request *api.SubmissionCreate) (*api.ID, error) {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrUserInfo
|
return nil, ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -55,7 +68,7 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
|
|||||||
creation_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
creation_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
||||||
Number: 1,
|
Number: 1,
|
||||||
Size: int32(CreationPhaseSubmissionsLimit),
|
Size: int32(CreationPhaseSubmissionsLimit),
|
||||||
})
|
},datastore.ListSortDisabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -74,7 +87,7 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
|
|||||||
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
||||||
Number: 1,
|
Number: 1,
|
||||||
Size: 1,
|
Size: 1,
|
||||||
})
|
},datastore.ListSortDisabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -83,23 +96,6 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if an active submission with the same target asset id exists
|
|
||||||
if request.TargetAssetID.IsSet() && request.TargetAssetID.Value != 0{
|
|
||||||
filter := datastore.Optional()
|
|
||||||
filter.Add("target_asset_id", request.TargetAssetID.Value)
|
|
||||||
filter.Add("status_id", ActiveSubmissionStatuses)
|
|
||||||
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
|
||||||
Number: 1,
|
|
||||||
Size: 1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(active_submissions) != 0{
|
|
||||||
return nil, ErrActiveSubmissionSameTargetAssetID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
submission, err := svc.DB.Submissions().Create(ctx, model.Submission{
|
submission, err := svc.DB.Submissions().Create(ctx, model.Submission{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
DisplayName: request.DisplayName,
|
DisplayName: request.DisplayName,
|
||||||
@@ -109,8 +105,7 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
|
|||||||
AssetID: request.AssetID,
|
AssetID: request.AssetID,
|
||||||
AssetVersion: request.AssetVersion,
|
AssetVersion: request.AssetVersion,
|
||||||
Completed: false,
|
Completed: false,
|
||||||
TargetAssetID: request.TargetAssetID.Value,
|
StatusID: model.SubmissionStatusUnderConstruction,
|
||||||
StatusID: model.StatusUnderConstruction,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -141,8 +136,9 @@ func (svc *Service) GetSubmission(ctx context.Context, params api.GetSubmissionP
|
|||||||
AssetID: int64(submission.AssetID),
|
AssetID: int64(submission.AssetID),
|
||||||
AssetVersion: int64(submission.AssetVersion),
|
AssetVersion: int64(submission.AssetVersion),
|
||||||
Completed: submission.Completed,
|
Completed: submission.Completed,
|
||||||
TargetAssetID: api.NewOptInt64(int64(submission.TargetAssetID)),
|
UploadedAssetID: api.NewOptInt64(int64(submission.UploadedAssetID)),
|
||||||
StatusID: int32(submission.StatusID),
|
StatusID: int32(submission.StatusID),
|
||||||
|
StatusMessage: submission.StatusMessage,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,29 +160,31 @@ func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissi
|
|||||||
filter.Add("game_id", params.GameID.Value)
|
filter.Add("game_id", params.GameID.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sort := datastore.ListSort(params.Sort.Or(int32(datastore.ListSortDisabled)))
|
||||||
|
|
||||||
items, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
items, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
||||||
Number: params.Page,
|
Number: params.Page,
|
||||||
Size: params.Limit,
|
Size: params.Limit,
|
||||||
})
|
},sort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp []api.Submission
|
var resp []api.Submission
|
||||||
for i := 0; i < len(items); i++ {
|
for _, item := range items {
|
||||||
resp = append(resp, api.Submission{
|
resp = append(resp, api.Submission{
|
||||||
ID: items[i].ID,
|
ID: item.ID,
|
||||||
DisplayName: items[i].DisplayName,
|
DisplayName: item.DisplayName,
|
||||||
Creator: items[i].Creator,
|
Creator: item.Creator,
|
||||||
GameID: items[i].GameID,
|
GameID: item.GameID,
|
||||||
CreatedAt: items[i].CreatedAt.Unix(),
|
CreatedAt: item.CreatedAt.Unix(),
|
||||||
UpdatedAt: items[i].UpdatedAt.Unix(),
|
UpdatedAt: item.UpdatedAt.Unix(),
|
||||||
Submitter: int64(items[i].Submitter),
|
Submitter: int64(item.Submitter),
|
||||||
AssetID: int64(items[i].AssetID),
|
AssetID: int64(item.AssetID),
|
||||||
AssetVersion: int64(items[i].AssetVersion),
|
AssetVersion: int64(item.AssetVersion),
|
||||||
Completed: items[i].Completed,
|
Completed: item.Completed,
|
||||||
TargetAssetID: api.NewOptInt64(int64(items[i].TargetAssetID)),
|
UploadedAssetID: api.NewOptInt64(int64(item.UploadedAssetID)),
|
||||||
StatusID: int32(items[i].StatusID),
|
StatusID: int32(item.StatusID),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +197,7 @@ func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissi
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/completed
|
// POST /submissions/{SubmissionID}/completed
|
||||||
func (svc *Service) SetSubmissionCompleted(ctx context.Context, params api.SetSubmissionCompletedParams) error {
|
func (svc *Service) SetSubmissionCompleted(ctx context.Context, params api.SetSubmissionCompletedParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -210,7 +208,7 @@ func (svc *Service) SetSubmissionCompleted(ctx context.Context, params api.SetSu
|
|||||||
}
|
}
|
||||||
// check if caller has MaptestGame role (request must originate from a maptest roblox game)
|
// check if caller has MaptestGame role (request must originate from a maptest roblox game)
|
||||||
if !has_role {
|
if !has_role {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDeniedNeedRoleMaptest
|
||||||
}
|
}
|
||||||
|
|
||||||
pmap := datastore.Optional()
|
pmap := datastore.Optional()
|
||||||
@@ -224,7 +222,7 @@ func (svc *Service) SetSubmissionCompleted(ctx context.Context, params api.SetSu
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/model
|
// POST /submissions/{SubmissionID}/model
|
||||||
func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.UpdateSubmissionModelParams) error {
|
func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.UpdateSubmissionModelParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -241,7 +239,7 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update
|
|||||||
}
|
}
|
||||||
// check if caller is the submitter
|
// check if caller is the submitter
|
||||||
if !has_role {
|
if !has_role {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDeniedNotSubmitter
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
||||||
@@ -250,7 +248,7 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update
|
|||||||
pmap.AddNotNil("asset_version", params.VersionID)
|
pmap.AddNotNil("asset_version", params.VersionID)
|
||||||
//always reset completed when model changes
|
//always reset completed when model changes
|
||||||
pmap.Add("completed", false)
|
pmap.Add("completed", false)
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusChangesRequested, model.StatusSubmitted, model.StatusUnderConstruction}, pmap)
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusChangesRequested, model.SubmissionStatusSubmitted, model.SubmissionStatusUnderConstruction}, pmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
||||||
@@ -259,7 +257,7 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/reject
|
// POST /submissions/{SubmissionID}/status/reject
|
||||||
func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.ActionSubmissionRejectParams) error {
|
func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.ActionSubmissionRejectParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -270,13 +268,13 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio
|
|||||||
}
|
}
|
||||||
// check if caller has required role
|
// check if caller has required role
|
||||||
if !has_role {
|
if !has_role {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
}
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusRejected)
|
smap.Add("status_id", model.SubmissionStatusRejected)
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted}, smap)
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
|
// ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
|
||||||
@@ -285,7 +283,7 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/request-changes
|
// POST /submissions/{SubmissionID}/status/request-changes
|
||||||
func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params api.ActionSubmissionRequestChangesParams) error {
|
func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params api.ActionSubmissionRequestChangesParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -296,13 +294,13 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a
|
|||||||
}
|
}
|
||||||
// check if caller has required role
|
// check if caller has required role
|
||||||
if !has_role {
|
if !has_role {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
}
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusChangesRequested)
|
smap.Add("status_id", model.SubmissionStatusChangesRequested)
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidated, model.StatusAccepted, model.StatusSubmitted}, smap)
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidated, model.SubmissionStatusAccepted, model.SubmissionStatusSubmitted}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
|
// ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
|
||||||
@@ -311,7 +309,7 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/revoke
|
// POST /submissions/{SubmissionID}/status/revoke
|
||||||
func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.ActionSubmissionRevokeParams) error {
|
func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.ActionSubmissionRevokeParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -328,13 +326,13 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio
|
|||||||
}
|
}
|
||||||
// check if caller is the submitter
|
// check if caller is the submitter
|
||||||
if !has_role {
|
if !has_role {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDeniedNotSubmitter
|
||||||
}
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusUnderConstruction)
|
smap.Add("status_id", model.SubmissionStatusUnderConstruction)
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted, model.StatusChangesRequested}, smap)
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted, model.SubmissionStatusChangesRequested}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionSubmit invokes actionSubmissionSubmit operation.
|
// ActionSubmissionSubmit invokes actionSubmissionSubmit operation.
|
||||||
@@ -343,7 +341,7 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/submit
|
// POST /submissions/{SubmissionID}/status/submit
|
||||||
func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.ActionSubmissionSubmitParams) error {
|
func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.ActionSubmissionSubmitParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -360,13 +358,13 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio
|
|||||||
}
|
}
|
||||||
// check if caller is the submitter
|
// check if caller is the submitter
|
||||||
if !has_role {
|
if !has_role {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDeniedNotSubmitter
|
||||||
}
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusSubmitted)
|
smap.Add("status_id", model.SubmissionStatusSubmitted)
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUnderConstruction, model.StatusChangesRequested}, smap)
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUnderConstruction, model.SubmissionStatusChangesRequested}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
||||||
@@ -375,72 +373,96 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/trigger-upload
|
// POST /submissions/{SubmissionID}/status/trigger-upload
|
||||||
func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params api.ActionSubmissionTriggerUploadParams) error {
|
func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params api.ActionSubmissionTriggerUploadParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
has_role, err := userInfo.HasRoleSubmissionRelease()
|
has_role, err := userInfo.HasRoleSubmissionUpload()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// check if caller has required role
|
// check if caller has required role
|
||||||
if !has_role {
|
if !has_role {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDeniedNeedRoleMapUpload
|
||||||
}
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusUploading)
|
smap.Add("status_id", model.SubmissionStatusUploading)
|
||||||
submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusValidated}, smap)
|
submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidated}, smap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// sentinel value because we are not using rust
|
// sentinel value because we are not using rust
|
||||||
if submission.TargetAssetID == 0 {
|
if submission.UploadedAssetID == 0 {
|
||||||
// this is a new map
|
// this is a new map
|
||||||
publish_new_request := model.PublishNewRequest{
|
upload_new_request := model.UploadNewRequest{
|
||||||
SubmissionID: submission.ID,
|
SubmissionID: submission.ID,
|
||||||
ModelID: submission.AssetID,
|
ModelID: submission.ValidatedAssetID,
|
||||||
ModelVersion: submission.AssetVersion,
|
ModelVersion: submission.ValidatedAssetVersion,
|
||||||
// publish as displayname, whatever
|
// upload as displayname, whatever
|
||||||
ModelName: submission.DisplayName,
|
ModelName: submission.DisplayName,
|
||||||
}
|
}
|
||||||
|
|
||||||
j, err := json.Marshal(publish_new_request)
|
j, err := json.Marshal(upload_new_request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
svc.Nats.Publish("maptest.submissions.publishnew", []byte(j))
|
svc.Nats.Publish("maptest.submissions.upload", []byte(j))
|
||||||
} else {
|
} else {
|
||||||
// this is a map fix
|
// refuse to operate
|
||||||
publish_fix_request := model.PublishFixRequest{
|
return ErrUploadedAssetIDAlreadyExists
|
||||||
SubmissionID: submission.ID,
|
|
||||||
ModelID: submission.AssetID,
|
|
||||||
ModelVersion: submission.AssetVersion,
|
|
||||||
TargetAssetID: submission.TargetAssetID,
|
|
||||||
}
|
|
||||||
|
|
||||||
j, err := json.Marshal(publish_fix_request)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
svc.Nats.Publish("maptest.submissions.publishfix", []byte(j))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
||||||
|
//
|
||||||
|
// Role SubmissionRelease changes status from Uploading -> Validated.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reset-uploading
|
||||||
|
func (svc *Service) ActionSubmissionValidated(ctx context.Context, params api.ActionSubmissionValidatedParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionUpload()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapUpload
|
||||||
|
}
|
||||||
|
|
||||||
|
// check when submission was updated
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if time.Now().Before(submission.UpdatedAt.Add(time.Second*10)) {
|
||||||
|
// the last time the submission was updated must be longer than 10 seconds ago
|
||||||
|
return ErrDelayReset
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusValidated)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUploading}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
|
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating.
|
// Role Reviewer triggers validation and changes status from Submitted -> Validating.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/trigger-validate
|
// POST /submissions/{SubmissionID}/status/trigger-validate
|
||||||
func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params api.ActionSubmissionTriggerValidateParams) error {
|
func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params api.ActionSubmissionTriggerValidateParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
}
|
}
|
||||||
@@ -451,13 +473,28 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
|
|||||||
}
|
}
|
||||||
// check if caller has required role
|
// check if caller has required role
|
||||||
if !has_role {
|
if !has_role {
|
||||||
return ErrPermissionDenied
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// read submission (this could be done with a transaction WHERE clause)
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err = userInfo.IsSubmitter(uint64(submission.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is NOT the submitter
|
||||||
|
if has_role {
|
||||||
|
return ErrAcceptOwnSubmission
|
||||||
}
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusValidating)
|
smap.Add("status_id", model.SubmissionStatusValidating)
|
||||||
submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted, model.StatusAccepted}, smap)
|
submission, err = svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted}, smap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -466,7 +503,12 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
|
|||||||
SubmissionID: submission.ID,
|
SubmissionID: submission.ID,
|
||||||
ModelID: submission.AssetID,
|
ModelID: submission.AssetID,
|
||||||
ModelVersion: submission.AssetVersion,
|
ModelVersion: submission.AssetVersion,
|
||||||
ValidatedModelID: 0, //TODO: reuse velidation models
|
ValidatedModelID: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sentinel values because we're not using rust
|
||||||
|
if submission.ValidatedAssetID != 0 {
|
||||||
|
validate_request.ValidatedModelID = &submission.ValidatedAssetID
|
||||||
}
|
}
|
||||||
|
|
||||||
j, err := json.Marshal(validate_request)
|
j, err := json.Marshal(validate_request)
|
||||||
@@ -478,3 +520,157 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionRetryValidate invokes actionSubmissionRetryValidate operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/retry-validate
|
||||||
|
func (svc *Service) ActionSubmissionRetryValidate(ctx context.Context, params api.ActionSubmissionRetryValidateParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusValidating)
|
||||||
|
submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusAccepted}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_request := model.ValidateRequest{
|
||||||
|
SubmissionID: submission.ID,
|
||||||
|
ModelID: submission.AssetID,
|
||||||
|
ModelVersion: submission.AssetVersion,
|
||||||
|
ValidatedModelID: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sentinel values because we're not using rust
|
||||||
|
if submission.ValidatedAssetID != 0 {
|
||||||
|
validate_request.ValidatedModelID = &submission.ValidatedAssetID
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(validate_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.submissions.validate", []byte(j))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
|
//
|
||||||
|
// Role SubmissionReview changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reset-validating
|
||||||
|
func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params api.ActionSubmissionAcceptedParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// check when submission was updated
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if time.Now().Before(submission.UpdatedAt.Add(time.Second*10)) {
|
||||||
|
// the last time the submission was updated must be longer than 10 seconds ago
|
||||||
|
return ErrDelayReset
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusAccepted)
|
||||||
|
smap.Add("status_message", "Manually forced reset")
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseSubmissions invokes releaseSubmissions operation.
|
||||||
|
//
|
||||||
|
// Release a set of uploaded maps.
|
||||||
|
//
|
||||||
|
// POST /release-submissions
|
||||||
|
func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.ReleaseInfo) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionRelease()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleSubmissionRelease
|
||||||
|
}
|
||||||
|
|
||||||
|
idList := make([]int64, len(request))
|
||||||
|
for i, releaseInfo := range request {
|
||||||
|
idList[i] = releaseInfo.SubmissionID
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch submissions
|
||||||
|
submissions, err := svc.DB.Submissions().GetList(ctx, idList)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check each submission to make sure it is ready to release
|
||||||
|
for _,submission := range submissions{
|
||||||
|
if submission.StatusID != model.SubmissionStatusUploaded{
|
||||||
|
return ErrReleaseInvalidStatus
|
||||||
|
}
|
||||||
|
if submission.UploadedAssetID == 0{
|
||||||
|
return ErrReleaseNoUploadedAssetID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i,submission := range submissions{
|
||||||
|
date := request[i].Date.Unix()
|
||||||
|
// create each map with go-grpc
|
||||||
|
_, err := svc.Client.Create(ctx, &maps.MapRequest{
|
||||||
|
ID: submission.UploadedAssetID,
|
||||||
|
DisplayName: &submission.DisplayName,
|
||||||
|
Creator: &submission.Creator,
|
||||||
|
GameID: &submission.GameID,
|
||||||
|
Date: &date,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// update each status to Released
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusReleased)
|
||||||
|
err = svc.DB.Submissions().IfStatusThenUpdate(ctx, submission.ID, []model.SubmissionStatus{model.SubmissionStatusUploaded}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,12 +67,12 @@ func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptP
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resp []api.ScriptPolicy
|
var resp []api.ScriptPolicy
|
||||||
for i := 0; i < len(items); i++ {
|
for _, item := range items {
|
||||||
resp = append(resp, api.ScriptPolicy{
|
resp = append(resp, api.ScriptPolicy{
|
||||||
ID: items[i].ID,
|
ID: item.ID,
|
||||||
FromScriptHash: model.HashFormat(uint64(items[i].FromScriptHash)),
|
FromScriptHash: model.HashFormat(uint64(item.FromScriptHash)),
|
||||||
ToScriptID: items[i].ToScriptID,
|
ToScriptID: item.ToScriptID,
|
||||||
Policy: int32(items[i].Policy),
|
Policy: int32(item.Policy),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*a
|
|||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
Hash: int64(model.HashSource(req.Source)),
|
Hash: int64(model.HashSource(req.Source)),
|
||||||
Source: req.Source,
|
Source: req.Source,
|
||||||
SubmissionID: req.SubmissionID.Or(0),
|
ResourceType: model.ResourceType(req.ResourceType),
|
||||||
|
ResourceID: req.ResourceID.Or(0),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -64,12 +65,13 @@ func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParam
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resp []api.Script
|
var resp []api.Script
|
||||||
for i := 0; i < len(items); i++ {
|
for _, item := range items {
|
||||||
resp = append(resp, api.Script{
|
resp = append(resp, api.Script{
|
||||||
ID: items[i].ID,
|
ID: item.ID,
|
||||||
Hash: model.HashFormat(uint64(items[i].Hash)),
|
Hash: model.HashFormat(uint64(item.Hash)),
|
||||||
Source: items[i].Source,
|
Source: item.Source,
|
||||||
SubmissionID: items[i].SubmissionID,
|
ResourceType: int32(item.ResourceType),
|
||||||
|
ResourceID: item.ResourceID,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +94,7 @@ func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (
|
|||||||
Name: script.Name,
|
Name: script.Name,
|
||||||
Hash: model.HashFormat(uint64(script.Hash)),
|
Hash: model.HashFormat(uint64(script.Hash)),
|
||||||
Source: script.Source,
|
Source: script.Source,
|
||||||
SubmissionID: script.SubmissionID,
|
ResourceType: int32(script.ResourceType),
|
||||||
|
ResourceID: script.ResourceID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,19 +8,19 @@ import (
|
|||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdateSubmissionModel implements patchSubmissionModel operation.
|
// UpdateSubmissionValidatedModel implements patchSubmissionModel operation.
|
||||||
//
|
//
|
||||||
// Update model following role restrictions.
|
// Update model following role restrictions.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/model
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
func (svc *Service) UpdateSubmissionModel(ctx context.Context, params internal.UpdateSubmissionModelParams) error {
|
func (svc *Service) UpdateSubmissionValidatedModel(ctx context.Context, params internal.UpdateSubmissionValidatedModelParams) error {
|
||||||
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
||||||
pmap := datastore.Optional()
|
pmap := datastore.Optional()
|
||||||
pmap.AddNotNil("asset_id", params.ModelID)
|
pmap.AddNotNil("validated_asset_id", params.ValidatedModelID)
|
||||||
pmap.AddNotNil("asset_version", params.VersionID)
|
pmap.AddNotNil("validated_asset_version", params.ValidatedModelVersion)
|
||||||
//always reset completed when model changes
|
// DO NOT reset completed when validated model is updated
|
||||||
pmap.Add("completed", false)
|
// pmap.Add("completed", false)
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, pmap)
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, pmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
||||||
@@ -29,12 +29,10 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params internal.U
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/validator-validated
|
// POST /submissions/{SubmissionID}/status/validator-validated
|
||||||
func (svc *Service) ActionSubmissionValidated(ctx context.Context, params internal.ActionSubmissionValidatedParams) error {
|
func (svc *Service) ActionSubmissionValidated(ctx context.Context, params internal.ActionSubmissionValidatedParams) error {
|
||||||
println("[ActionSubmissionValidated] Implicit Validator permission granted!")
|
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusValidated)
|
smap.Add("status_id", model.SubmissionStatusValidated)
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
@@ -43,26 +41,11 @@ func (svc *Service) ActionSubmissionValidated(ctx context.Context, params intern
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/validator-failed
|
// POST /submissions/{SubmissionID}/status/validator-failed
|
||||||
func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params internal.ActionSubmissionAcceptedParams) error {
|
func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params internal.ActionSubmissionAcceptedParams) error {
|
||||||
println("[ActionSubmissionAccepted] Implicit Validator permission granted!")
|
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusAccepted)
|
smap.Add("status_id", model.SubmissionStatusAccepted)
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
|
smap.Add("status_message", params.StatusMessage)
|
||||||
}
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
|
||||||
|
|
||||||
// ActionSubmissionReleased implements actionSubmissionReleased operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Releaser changes status from Uploaded -> Released.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/releaser-released
|
|
||||||
func (svc *Service) ActionSubmissionReleased(ctx context.Context, params internal.ActionSubmissionReleasedParams) error {
|
|
||||||
println("[ActionSubmissionReleased] Implicit Validator permission granted!")
|
|
||||||
|
|
||||||
// transaction
|
|
||||||
smap := datastore.Optional()
|
|
||||||
smap.Add("status_id", model.StatusReleased)
|
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUploaded}, smap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
||||||
@@ -71,13 +54,9 @@ func (svc *Service) ActionSubmissionReleased(ctx context.Context, params interna
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/validator-uploaded
|
// POST /submissions/{SubmissionID}/status/validator-uploaded
|
||||||
func (svc *Service) ActionSubmissionUploaded(ctx context.Context, params internal.ActionSubmissionUploadedParams) error {
|
func (svc *Service) ActionSubmissionUploaded(ctx context.Context, params internal.ActionSubmissionUploadedParams) error {
|
||||||
println("[ActionSubmissionUploaded] Implicit Validator permission granted!")
|
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.StatusUploaded)
|
smap.Add("status_id", model.SubmissionStatusUploaded)
|
||||||
if params.TargetAssetID.IsSet() {
|
smap.Add("uploaded_asset_id", params.UploadedAssetID)
|
||||||
smap.AddNotNil("target_asset_id", params.TargetAssetID.Value)
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUploading}, smap)
|
||||||
}
|
|
||||||
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUploading}, smap)
|
|
||||||
}
|
}
|
||||||
|
|||||||
1
validation/.gitignore
vendored
1
validation/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
/target
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "maps-validation"
|
name = "maps-validation"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
submissions-api = { path = "api", features = ["internal"], registry = "strafesnet" }
|
submissions-api = { path = "api", features = ["internal"], default-features = false, registry = "strafesnet" }
|
||||||
async-nats = "0.38.0"
|
async-nats = "0.40.0"
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
rbx_asset = { version = "0.2.5", registry = "strafesnet" }
|
rbx_asset = { version = "0.2.5", registry = "strafesnet" }
|
||||||
rbx_binary = { version = "0.7.4", registry = "strafesnet"}
|
rbx_binary = { version = "0.7.4", registry = "strafesnet"}
|
||||||
|
|||||||
1
validation/api/.gitignore
vendored
1
validation/api/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
/target
|
|
||||||
1463
validation/api/Cargo.lock
generated
1463
validation/api/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "submissions-api"
|
name = "submissions-api"
|
||||||
version = "0.3.0"
|
version = "0.6.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = ["strafesnet"]
|
publish = ["strafesnet"]
|
||||||
repository = "https://git.itzana.me/StrafesNET/maps-service"
|
repository = "https://git.itzana.me/StrafesNET/maps-service"
|
||||||
@@ -18,6 +18,6 @@ serde_repr = "0.1.19"
|
|||||||
url = "2"
|
url = "2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["internal"]
|
default = ["external"]
|
||||||
internal = []
|
internal = []
|
||||||
external = []
|
external = []
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ pub struct Context{
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Context{
|
impl Context{
|
||||||
pub fn new(mut base_url:String,cookie:Option<Cookie>)->reqwest::Result<Self>{
|
pub fn new(base_url:String,cookie:Option<Cookie>)->reqwest::Result<Self>{
|
||||||
base_url+="/v1";
|
|
||||||
Ok(Self{
|
Ok(Self{
|
||||||
base_url,
|
base_url,
|
||||||
client:{
|
client:{
|
||||||
|
|||||||
@@ -31,6 +31,47 @@ impl Context{
|
|||||||
).await.map_err(Error::Response)?
|
).await.map_err(Error::Response)?
|
||||||
.json().await.map_err(Error::Reqwest)
|
.json().await.map_err(Error::Reqwest)
|
||||||
}
|
}
|
||||||
|
pub async fn get_scripts<'a>(&self,config:GetScriptsRequest<'a>)->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(submission_id)=config.SubmissionID{
|
||||||
|
query_pairs.append_pair("SubmissionID",submission_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::Reqwest)
|
||||||
|
}
|
||||||
|
pub async fn get_script_from_hash<'a>(&self,config:HashRequest<'a>)->Result<Option<ScriptResponse>,SingleItemError>{
|
||||||
|
let scripts=self.get_scripts(GetScriptsRequest{
|
||||||
|
Page:1,
|
||||||
|
Limit:2,
|
||||||
|
Hash:Some(config.hash),
|
||||||
|
Name:None,
|
||||||
|
Source:None,
|
||||||
|
SubmissionID:None,
|
||||||
|
}).await.map_err(SingleItemError::Other)?;
|
||||||
|
if 1<scripts.len(){
|
||||||
|
return Err(SingleItemError::DuplicateItems);
|
||||||
|
}
|
||||||
|
Ok(scripts.into_iter().next())
|
||||||
|
}
|
||||||
pub async fn create_script<'a>(&self,config:CreateScriptRequest<'a>)->Result<ScriptIDResponse,Error>{
|
pub async fn create_script<'a>(&self,config:CreateScriptRequest<'a>)->Result<ScriptIDResponse,Error>{
|
||||||
let url_raw=format!("{}/scripts",self.0.base_url);
|
let url_raw=format!("{}/scripts",self.0.base_url);
|
||||||
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
@@ -90,14 +131,14 @@ impl Context{
|
|||||||
).await.map_err(Error::Response)?
|
).await.map_err(Error::Response)?
|
||||||
.json().await.map_err(Error::Reqwest)
|
.json().await.map_err(Error::Reqwest)
|
||||||
}
|
}
|
||||||
pub async fn update_submission_model(&self,config:UpdateSubmissionModelRequest)->Result<(),Error>{
|
pub async fn update_submission_validated_model(&self,config:UpdateSubmissionModelRequest)->Result<(),Error>{
|
||||||
let url_raw=format!("{}/submissions/{}/model",self.0.base_url,config.SubmissionID);
|
let url_raw=format!("{}/submissions/{}/validated-model",self.0.base_url,config.SubmissionID);
|
||||||
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("ModelID",config.ModelID.to_string().as_str())
|
.append_pair("ValidatedModelID",config.ModelID.to_string().as_str())
|
||||||
.append_pair("ModelVersion",config.ModelVersion.to_string().as_str());
|
.append_pair("ValidatedModelVersion",config.ModelVersion.to_string().as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
response_ok(
|
response_ok(
|
||||||
@@ -110,9 +151,9 @@ impl Context{
|
|||||||
let url_raw=format!("{}/submissions/{}/status/validator-uploaded",self.0.base_url,config.SubmissionID);
|
let url_raw=format!("{}/submissions/{}/status/validator-uploaded",self.0.base_url,config.SubmissionID);
|
||||||
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
if let Some(target_asset_id)=config.TargetAssetID{
|
{
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("TargetAssetID",target_asset_id.to_string().as_str());
|
.append_pair("UploadedAssetID",config.UploadedAssetID.to_string().as_str());
|
||||||
}
|
}
|
||||||
response_ok(
|
response_ok(
|
||||||
self.0.post_empty_body(url).await.map_err(Error::Reqwest)?
|
self.0.post_empty_body(url).await.map_err(Error::Reqwest)?
|
||||||
@@ -120,7 +161,20 @@ impl Context{
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub async fn action_submission_accepted(&self,config:ActionSubmissionAcceptedRequest)->Result<(),Error>{
|
||||||
|
let url_raw=format!("{}/submissions/{}/status/validator-failed",self.0.base_url,config.SubmissionID);
|
||||||
|
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
{
|
||||||
|
url.query_pairs_mut()
|
||||||
|
.append_pair("StatusMessage",config.StatusMessage.as_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post_empty_body(url).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
action!(action_submission_validated,"validator-validated");
|
action!(action_submission_validated,"validator-validated");
|
||||||
action!(action_submission_accepted,"validator-failed");
|
|
||||||
action!(action_submission_released,"releaser-released");
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ pub async fn response_ok(response:reqwest::Response)->Result<reqwest::Response,R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,PartialEq,Eq,serde::Serialize,serde::Deserialize)]
|
#[derive(Clone,Copy,Debug,PartialEq,Eq,serde::Serialize,serde::Deserialize)]
|
||||||
pub struct ScriptID(pub(crate)i64);
|
pub struct ScriptID(pub(crate)i64);
|
||||||
#[derive(Clone,Copy,serde::Serialize,serde::Deserialize)]
|
#[derive(Clone,Copy,Debug,serde::Serialize,serde::Deserialize)]
|
||||||
pub struct ScriptPolicyID(pub(crate)i64);
|
pub struct ScriptPolicyID(pub(crate)i64);
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
@@ -70,7 +70,7 @@ pub struct GetScriptRequest{
|
|||||||
pub ScriptID:ScriptID,
|
pub ScriptID:ScriptID,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
pub struct GetScriptsRequest<'a>{
|
pub struct GetScriptsRequest<'a>{
|
||||||
pub Page:u32,
|
pub Page:u32,
|
||||||
pub Limit:u32,
|
pub Limit:u32,
|
||||||
@@ -83,11 +83,12 @@ pub struct GetScriptsRequest<'a>{
|
|||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub SubmissionID:Option<i64>,
|
pub SubmissionID:Option<i64>,
|
||||||
}
|
}
|
||||||
|
#[derive(Clone,Copy,Debug)]
|
||||||
pub struct HashRequest<'a>{
|
pub struct HashRequest<'a>{
|
||||||
pub hash:&'a str,
|
pub hash:&'a str,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
pub struct ScriptResponse{
|
pub struct ScriptResponse{
|
||||||
pub ID:ScriptID,
|
pub ID:ScriptID,
|
||||||
pub Name:String,
|
pub Name:String,
|
||||||
@@ -95,21 +96,28 @@ pub struct ScriptResponse{
|
|||||||
pub Source:String,
|
pub Source:String,
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:i64,
|
||||||
}
|
}
|
||||||
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
|
pub enum ResourceType{
|
||||||
|
Unknown=0,
|
||||||
|
Mapfix=1,
|
||||||
|
Submission=2,
|
||||||
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
pub struct CreateScriptRequest<'a>{
|
pub struct CreateScriptRequest<'a>{
|
||||||
pub Name:&'a str,
|
pub Name:&'a str,
|
||||||
pub Source:&'a str,
|
pub Source:&'a str,
|
||||||
|
pub ResourceType:ResourceType,
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub SubmissionID:Option<i64>,
|
pub ResourceID:Option<i64>,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
pub struct ScriptIDResponse{
|
pub struct ScriptIDResponse{
|
||||||
pub ID:ScriptID,
|
pub ID:ScriptID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq,Eq,serde_repr::Serialize_repr,serde_repr::Deserialize_repr)]
|
#[derive(Clone,Copy,Debug,PartialEq,Eq,serde_repr::Serialize_repr,serde_repr::Deserialize_repr)]
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
pub enum Policy{
|
pub enum Policy{
|
||||||
None=0, // not yet reviewed
|
None=0, // not yet reviewed
|
||||||
@@ -120,7 +128,7 @@ pub enum Policy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
pub struct GetScriptPoliciesRequest<'a>{
|
pub struct GetScriptPoliciesRequest<'a>{
|
||||||
pub Page:u32,
|
pub Page:u32,
|
||||||
pub Limit:u32,
|
pub Limit:u32,
|
||||||
@@ -132,7 +140,7 @@ pub struct GetScriptPoliciesRequest<'a>{
|
|||||||
pub Policy:Option<Policy>,
|
pub Policy:Option<Policy>,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
pub struct ScriptPolicyResponse{
|
pub struct ScriptPolicyResponse{
|
||||||
pub ID:ScriptPolicyID,
|
pub ID:ScriptPolicyID,
|
||||||
pub FromScriptHash:String,
|
pub FromScriptHash:String,
|
||||||
@@ -140,20 +148,20 @@ pub struct ScriptPolicyResponse{
|
|||||||
pub Policy:Policy
|
pub Policy:Policy
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
pub struct CreateScriptPolicyRequest{
|
pub struct CreateScriptPolicyRequest{
|
||||||
pub FromScriptID:ScriptID,
|
pub FromScriptID:ScriptID,
|
||||||
pub ToScriptID:ScriptID,
|
pub ToScriptID:ScriptID,
|
||||||
pub Policy:Policy,
|
pub Policy:Policy,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
pub struct ScriptPolicyIDResponse{
|
pub struct ScriptPolicyIDResponse{
|
||||||
pub ID:ScriptPolicyID,
|
pub ID:ScriptPolicyID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
pub struct UpdateScriptPolicyRequest{
|
pub struct UpdateScriptPolicyRequest{
|
||||||
pub ID:ScriptPolicyID,
|
pub ID:ScriptPolicyID,
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@@ -165,6 +173,7 @@ pub struct UpdateScriptPolicyRequest{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
pub struct UpdateSubmissionModelRequest{
|
pub struct UpdateSubmissionModelRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:i64,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
@@ -172,9 +181,42 @@ pub struct UpdateSubmissionModelRequest{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionSubmissionUploadedRequest{
|
pub struct ActionSubmissionUploadedRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:i64,
|
||||||
pub TargetAssetID:Option<u64>,
|
pub UploadedAssetID:u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct ActionSubmissionAcceptedRequest{
|
||||||
|
pub SubmissionID:i64,
|
||||||
|
pub StatusMessage:String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Debug)]
|
||||||
pub struct SubmissionID(pub i64);
|
pub struct SubmissionID(pub i64);
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct UpdateMapfixModelRequest{
|
||||||
|
pub MapfixID:i64,
|
||||||
|
pub ModelID:u64,
|
||||||
|
pub ModelVersion:u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct ActionMapfixUploadedRequest{
|
||||||
|
pub MapfixID:i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct ActionMapfixAcceptedRequest{
|
||||||
|
pub MapfixID:i64,
|
||||||
|
pub StatusMessage:String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Debug)]
|
||||||
|
pub struct MapfixID(pub i64);
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
|
||||||
mod nats_types;
|
|
||||||
mod validator;
|
|
||||||
mod publish_new;
|
|
||||||
mod publish_fix;
|
|
||||||
mod message_handler;
|
mod message_handler;
|
||||||
|
mod nats_types;
|
||||||
|
mod types;
|
||||||
|
mod uploader;
|
||||||
|
mod upload_mapfix;
|
||||||
|
mod upload_submission;
|
||||||
|
mod validator;
|
||||||
|
mod validate_mapfix;
|
||||||
|
mod validate_submission;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -52,7 +56,7 @@ async fn main()->Result<(),StartupError>{
|
|||||||
.get_or_create_consumer("validation",async_nats::jetstream::consumer::pull::Config{
|
.get_or_create_consumer("validation",async_nats::jetstream::consumer::pull::Config{
|
||||||
name:Some("validation".to_owned()),
|
name:Some("validation".to_owned()),
|
||||||
durable_name:Some("validation".to_owned()),
|
durable_name:Some("validation".to_owned()),
|
||||||
filter_subject:"maptest.submissions.>".to_owned(),
|
filter_subject:"maptest.>".to_owned(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}).await.map_err(StartupError::NatsConsumer)?
|
}).await.map_err(StartupError::NatsConsumer)?
|
||||||
.messages().await.map_err(StartupError::NatsStream)
|
.messages().await.map_err(StartupError::NatsStream)
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ pub enum HandleMessageError{
|
|||||||
DoubleAck(async_nats::Error),
|
DoubleAck(async_nats::Error),
|
||||||
Json(serde_json::Error),
|
Json(serde_json::Error),
|
||||||
UnknownSubject(String),
|
UnknownSubject(String),
|
||||||
PublishNew(crate::publish_new::PublishError),
|
UploadMapfix(crate::upload_mapfix::UploadError),
|
||||||
PublishFix(crate::publish_fix::PublishError),
|
UploadSubmission(crate::upload_submission::UploadError),
|
||||||
Validation(crate::validator::ValidateError),
|
ValidateMapfix(crate::validate_mapfix::ValidateMapfixError),
|
||||||
|
ValidateSubmission(crate::validate_submission::ValidateSubmissionError),
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for HandleMessageError{
|
impl std::fmt::Display for HandleMessageError{
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
@@ -23,9 +24,10 @@ fn from_slice<'a,T:serde::de::Deserialize<'a>>(slice:&'a [u8])->Result<T,HandleM
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct MessageHandler{
|
pub struct MessageHandler{
|
||||||
publish_new:crate::publish_new::Publisher,
|
upload_mapfix:crate::upload_mapfix::Uploader,
|
||||||
publish_fix:crate::publish_fix::Publisher,
|
upload_submission:crate::upload_submission::Uploader,
|
||||||
validator:crate::validator::Validator,
|
validate_mapfix:crate::validate_mapfix::Validator,
|
||||||
|
validate_submission:crate::validate_submission::Validator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MessageHandler{
|
impl MessageHandler{
|
||||||
@@ -35,18 +37,20 @@ impl MessageHandler{
|
|||||||
api:submissions_api::internal::Context,
|
api:submissions_api::internal::Context,
|
||||||
)->Self{
|
)->Self{
|
||||||
Self{
|
Self{
|
||||||
publish_new:crate::publish_new::Publisher::new(cookie_context.clone(),group_id,api.clone()),
|
upload_mapfix:crate::upload_mapfix::Uploader::new(crate::uploader::Uploader::new(cookie_context.clone(),group_id,api.clone())),
|
||||||
publish_fix:crate::publish_fix::Publisher::new(cookie_context.clone(),group_id,api.clone()),
|
upload_submission:crate::upload_submission::Uploader::new(crate::uploader::Uploader::new(cookie_context.clone(),group_id,api.clone())),
|
||||||
validator:crate::validator::Validator::new(cookie_context,api),
|
validate_mapfix:crate::validate_mapfix::Validator::new(crate::validator::Validator::new(cookie_context.clone(),api.clone())),
|
||||||
|
validate_submission:crate::validate_submission::Validator::new(crate::validator::Validator::new(cookie_context,api)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub async fn handle_message_result(&self,message_result:MessageResult)->Result<(),HandleMessageError>{
|
pub async fn handle_message_result(&self,message_result:MessageResult)->Result<(),HandleMessageError>{
|
||||||
let message=message_result.map_err(HandleMessageError::Messages)?;
|
let message=message_result.map_err(HandleMessageError::Messages)?;
|
||||||
message.double_ack().await.map_err(HandleMessageError::DoubleAck)?;
|
message.double_ack().await.map_err(HandleMessageError::DoubleAck)?;
|
||||||
match message.subject.as_str(){
|
match message.subject.as_str(){
|
||||||
"maptest.submissions.publishnew"=>self.publish_new.publish(from_slice(&message.payload)?).await.map_err(HandleMessageError::PublishNew),
|
"maptest.mapfixes.upload"=>self.upload_mapfix.upload(from_slice(&message.payload)?).await.map_err(HandleMessageError::UploadMapfix),
|
||||||
"maptest.submissions.publishfix"=>self.publish_fix.publish(from_slice(&message.payload)?).await.map_err(HandleMessageError::PublishFix),
|
"maptest.submissions.upload"=>self.upload_submission.upload(from_slice(&message.payload)?).await.map_err(HandleMessageError::UploadSubmission),
|
||||||
"maptest.submissions.validate"=>self.validator.validate(from_slice(&message.payload)?).await.map_err(HandleMessageError::Validation),
|
"maptest.mapfixes.validate"=>self.validate_mapfix.validate(from_slice(&message.payload)?).await.map_err(HandleMessageError::ValidateMapfix),
|
||||||
|
"maptest.submissions.validate"=>self.validate_submission.validate(from_slice(&message.payload)?).await.map_err(HandleMessageError::ValidateSubmission),
|
||||||
other=>Err(HandleMessageError::UnknownSubject(other.to_owned()))
|
other=>Err(HandleMessageError::UnknownSubject(other.to_owned()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct ValidateRequest{
|
pub struct ValidateSubmissionRequest{
|
||||||
// submission_id is passed back in the response message
|
// submission_id is passed back in the response message
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:i64,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
@@ -14,10 +14,20 @@ pub struct ValidateRequest{
|
|||||||
pub ValidatedModelID:Option<u64>,
|
pub ValidatedModelID:Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
pub struct ValidateMapfixRequest{
|
||||||
|
// submission_id is passed back in the response message
|
||||||
|
pub MapfixID:i64,
|
||||||
|
pub ModelID:u64,
|
||||||
|
pub ModelVersion:u64,
|
||||||
|
pub ValidatedModelID:Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new map
|
// Create a new map
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct PublishNewRequest{
|
pub struct UploadSubmissionRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:i64,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
@@ -26,8 +36,8 @@ pub struct PublishNewRequest{
|
|||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct PublishFixRequest{
|
pub struct UploadMapfixRequest{
|
||||||
pub SubmissionID:i64,
|
pub MapfixID:i64,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
pub TargetAssetID:u64,
|
pub TargetAssetID:u64,
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
use crate::nats_types::PublishFixRequest;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum PublishError{
|
|
||||||
Get(rbx_asset::cookie::GetError),
|
|
||||||
Json(serde_json::Error),
|
|
||||||
Upload(rbx_asset::cookie::UploadError),
|
|
||||||
ApiActionSubmissionUploaded(submissions_api::Error),
|
|
||||||
}
|
|
||||||
impl std::fmt::Display for PublishError{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
write!(f,"{self:?}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl std::error::Error for PublishError{}
|
|
||||||
|
|
||||||
pub struct Publisher{
|
|
||||||
roblox_cookie:rbx_asset::cookie::CookieContext,
|
|
||||||
group_id:Option<u64>,
|
|
||||||
api_internal:submissions_api::internal::Context,
|
|
||||||
}
|
|
||||||
impl Publisher{
|
|
||||||
pub const fn new(
|
|
||||||
roblox_cookie:rbx_asset::cookie::CookieContext,
|
|
||||||
group_id:Option<u64>,
|
|
||||||
api_internal:submissions_api::internal::Context,
|
|
||||||
)->Self{
|
|
||||||
Self{
|
|
||||||
roblox_cookie,
|
|
||||||
group_id,
|
|
||||||
api_internal,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub async fn publish(&self,publish_info:PublishFixRequest)->Result<(),PublishError>{
|
|
||||||
// download the map model version
|
|
||||||
let model_data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
|
|
||||||
asset_id:publish_info.ModelID,
|
|
||||||
version:Some(publish_info.ModelVersion),
|
|
||||||
}).await.map_err(PublishError::Get)?;
|
|
||||||
|
|
||||||
// upload the map to the strafesnet group
|
|
||||||
let _upload_response=self.roblox_cookie.upload(rbx_asset::cookie::UploadRequest{
|
|
||||||
assetid:publish_info.TargetAssetID,
|
|
||||||
groupId:self.group_id,
|
|
||||||
name:None,
|
|
||||||
description:None,
|
|
||||||
ispublic:None,
|
|
||||||
allowComments:None,
|
|
||||||
},model_data).await.map_err(PublishError::Upload)?;
|
|
||||||
|
|
||||||
// that's it, the database entry does not need to be changed.
|
|
||||||
|
|
||||||
// mark submission as uploaded, TargetAssetID is unchanged
|
|
||||||
self.api_internal.action_submission_uploaded(submissions_api::types::ActionSubmissionUploadedRequest{
|
|
||||||
SubmissionID:publish_info.SubmissionID,
|
|
||||||
TargetAssetID:None,
|
|
||||||
}).await.map_err(PublishError::ApiActionSubmissionUploaded)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
use crate::nats_types::PublishNewRequest;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum PublishError{
|
|
||||||
Get(rbx_asset::cookie::GetError),
|
|
||||||
Json(serde_json::Error),
|
|
||||||
Create(rbx_asset::cookie::CreateError),
|
|
||||||
SystemTime(std::time::SystemTimeError),
|
|
||||||
ApiActionSubmissionPublish(submissions_api::Error),
|
|
||||||
}
|
|
||||||
impl std::fmt::Display for PublishError{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
write!(f,"{self:?}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl std::error::Error for PublishError{}
|
|
||||||
|
|
||||||
pub struct Publisher{
|
|
||||||
roblox_cookie:rbx_asset::cookie::CookieContext,
|
|
||||||
group_id:Option<u64>,
|
|
||||||
api:submissions_api::internal::Context,
|
|
||||||
}
|
|
||||||
impl Publisher{
|
|
||||||
pub const fn new(
|
|
||||||
roblox_cookie:rbx_asset::cookie::CookieContext,
|
|
||||||
group_id:Option<u64>,
|
|
||||||
api:submissions_api::internal::Context,
|
|
||||||
)->Self{
|
|
||||||
Self{
|
|
||||||
roblox_cookie,
|
|
||||||
group_id,
|
|
||||||
api,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub async fn publish(&self,publish_info:PublishNewRequest)->Result<(),PublishError>{
|
|
||||||
// download the map model version
|
|
||||||
let model_data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
|
|
||||||
asset_id:publish_info.ModelID,
|
|
||||||
version:Some(publish_info.ModelVersion),
|
|
||||||
}).await.map_err(PublishError::Get)?;
|
|
||||||
|
|
||||||
// upload the map to the strafesnet group
|
|
||||||
let upload_response=self.roblox_cookie.create(rbx_asset::cookie::CreateRequest{
|
|
||||||
name:publish_info.ModelName.clone(),
|
|
||||||
description:"".to_owned(),
|
|
||||||
ispublic:false,
|
|
||||||
allowComments:false,
|
|
||||||
groupId:self.group_id,
|
|
||||||
},model_data).await.map_err(PublishError::Create)?;
|
|
||||||
|
|
||||||
// note the asset id of the created model for later release, and mark the submission as uploaded
|
|
||||||
self.api.action_submission_uploaded(submissions_api::types::ActionSubmissionUploadedRequest{
|
|
||||||
SubmissionID:publish_info.SubmissionID,
|
|
||||||
TargetAssetID:Some(upload_response.AssetId),
|
|
||||||
}).await.map_err(PublishError::ApiActionSubmissionPublish)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
validation/src/types.rs
Normal file
4
validation/src/types.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
pub enum ResourceID{
|
||||||
|
Mapfix(i64),
|
||||||
|
Submission(i64),
|
||||||
|
}
|
||||||
50
validation/src/upload_mapfix.rs
Normal file
50
validation/src/upload_mapfix.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use crate::nats_types::UploadMapfixRequest;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UploadError{
|
||||||
|
Get(rbx_asset::cookie::GetError),
|
||||||
|
Json(serde_json::Error),
|
||||||
|
Upload(rbx_asset::cookie::UploadError),
|
||||||
|
ApiActionMapfixUploaded(submissions_api::Error),
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for UploadError{
|
||||||
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
|
write!(f,"{self:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::error::Error for UploadError{}
|
||||||
|
|
||||||
|
pub struct Uploader(crate::uploader::Uploader);
|
||||||
|
impl Uploader{
|
||||||
|
pub const fn new(inner:crate::uploader::Uploader)->Self{
|
||||||
|
Self(inner)
|
||||||
|
}
|
||||||
|
pub async fn upload(&self,upload_info:UploadMapfixRequest)->Result<(),UploadError>{
|
||||||
|
let Self(uploader)=self;
|
||||||
|
// download the map model version
|
||||||
|
let model_data=uploader.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
|
||||||
|
asset_id:upload_info.ModelID,
|
||||||
|
version:Some(upload_info.ModelVersion),
|
||||||
|
}).await.map_err(UploadError::Get)?;
|
||||||
|
|
||||||
|
// upload the map to the strafesnet group
|
||||||
|
let _upload_response=uploader.roblox_cookie.upload(rbx_asset::cookie::UploadRequest{
|
||||||
|
assetid:upload_info.TargetAssetID,
|
||||||
|
groupId:uploader.group_id,
|
||||||
|
name:None,
|
||||||
|
description:None,
|
||||||
|
ispublic:None,
|
||||||
|
allowComments:None,
|
||||||
|
},model_data).await.map_err(UploadError::Upload)?;
|
||||||
|
|
||||||
|
// that's it, the database entry does not need to be changed.
|
||||||
|
|
||||||
|
// mark mapfix as uploaded, TargetAssetID is unchanged
|
||||||
|
uploader.api.action_mapfix_uploaded(submissions_api::types::ActionMapfixUploadedRequest{
|
||||||
|
MapfixID:upload_info.MapfixID,
|
||||||
|
}).await.map_err(UploadError::ApiActionMapfixUploaded)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
49
validation/src/upload_submission.rs
Normal file
49
validation/src/upload_submission.rs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
use crate::nats_types::UploadSubmissionRequest;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UploadError{
|
||||||
|
Get(rbx_asset::cookie::GetError),
|
||||||
|
Json(serde_json::Error),
|
||||||
|
Create(rbx_asset::cookie::CreateError),
|
||||||
|
SystemTime(std::time::SystemTimeError),
|
||||||
|
ApiActionSubmissionUploaded(submissions_api::Error),
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for UploadError{
|
||||||
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
|
write!(f,"{self:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::error::Error for UploadError{}
|
||||||
|
|
||||||
|
pub struct Uploader(crate::uploader::Uploader);
|
||||||
|
impl Uploader{
|
||||||
|
pub const fn new(inner:crate::uploader::Uploader)->Self{
|
||||||
|
Self(inner)
|
||||||
|
}
|
||||||
|
pub async fn upload(&self,upload_info:UploadSubmissionRequest)->Result<(),UploadError>{
|
||||||
|
let Self(uploader)=self;
|
||||||
|
// download the map model version
|
||||||
|
let model_data=uploader.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
|
||||||
|
asset_id:upload_info.ModelID,
|
||||||
|
version:Some(upload_info.ModelVersion),
|
||||||
|
}).await.map_err(UploadError::Get)?;
|
||||||
|
|
||||||
|
// upload the map to the strafesnet group
|
||||||
|
let upload_response=uploader.roblox_cookie.create(rbx_asset::cookie::CreateRequest{
|
||||||
|
name:upload_info.ModelName.clone(),
|
||||||
|
description:"".to_owned(),
|
||||||
|
ispublic:false,
|
||||||
|
allowComments:false,
|
||||||
|
groupId:uploader.group_id,
|
||||||
|
},model_data).await.map_err(UploadError::Create)?;
|
||||||
|
|
||||||
|
// note the asset id of the created model for later release, and mark the submission as uploaded
|
||||||
|
uploader.api.action_submission_uploaded(submissions_api::types::ActionSubmissionUploadedRequest{
|
||||||
|
SubmissionID:upload_info.SubmissionID,
|
||||||
|
UploadedAssetID:upload_response.AssetId,
|
||||||
|
}).await.map_err(UploadError::ApiActionSubmissionUploaded)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
18
validation/src/uploader.rs
Normal file
18
validation/src/uploader.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
pub struct Uploader{
|
||||||
|
pub(crate) roblox_cookie:rbx_asset::cookie::CookieContext,
|
||||||
|
pub(crate) group_id:Option<u64>,
|
||||||
|
pub(crate) api:submissions_api::internal::Context,
|
||||||
|
}
|
||||||
|
impl Uploader{
|
||||||
|
pub const fn new(
|
||||||
|
roblox_cookie:rbx_asset::cookie::CookieContext,
|
||||||
|
group_id:Option<u64>,
|
||||||
|
api:submissions_api::internal::Context,
|
||||||
|
)->Self{
|
||||||
|
Self{
|
||||||
|
roblox_cookie,
|
||||||
|
group_id,
|
||||||
|
api,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
validation/src/validate_mapfix.rs
Normal file
45
validation/src/validate_mapfix.rs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
use crate::nats_types::ValidateMapfixRequest;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ValidateMapfixError{
|
||||||
|
ApiActionMapfixValidate(submissions_api::Error),
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for ValidateMapfixError{
|
||||||
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
|
write!(f,"{self:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::error::Error for ValidateMapfixError{}
|
||||||
|
|
||||||
|
pub struct Validator(crate::validator::Validator);
|
||||||
|
impl Validator{
|
||||||
|
pub const fn new(inner:crate::validator::Validator)->Self{
|
||||||
|
Self(inner)
|
||||||
|
}
|
||||||
|
pub async fn validate(&self,validate_info:ValidateMapfixRequest)->Result<(),ValidateMapfixError>{
|
||||||
|
let Self(validator)=self;
|
||||||
|
|
||||||
|
let mapfix_id=validate_info.MapfixID;
|
||||||
|
let validate_result=validator.validate(validate_info.into()).await;
|
||||||
|
|
||||||
|
// update the mapfix depending on the result
|
||||||
|
match &validate_result{
|
||||||
|
Ok(())=>{
|
||||||
|
// update the mapfix model status to validated
|
||||||
|
validator.api.action_mapfix_validated(
|
||||||
|
submissions_api::types::MapfixID(mapfix_id)
|
||||||
|
).await.map_err(ValidateMapfixError::ApiActionMapfixValidate)?;
|
||||||
|
},
|
||||||
|
Err(e)=>{
|
||||||
|
// update the mapfix model status to accepted
|
||||||
|
validator.api.action_mapfix_accepted(submissions_api::types::ActionMapfixAcceptedRequest{
|
||||||
|
MapfixID:mapfix_id,
|
||||||
|
StatusMessage:format!("{e}"),
|
||||||
|
}).await.map_err(ValidateMapfixError::ApiActionMapfixValidate)?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
45
validation/src/validate_submission.rs
Normal file
45
validation/src/validate_submission.rs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
use crate::nats_types::ValidateSubmissionRequest;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ValidateSubmissionError{
|
||||||
|
ApiActionSubmissionValidate(submissions_api::Error),
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for ValidateSubmissionError{
|
||||||
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
|
write!(f,"{self:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::error::Error for ValidateSubmissionError{}
|
||||||
|
|
||||||
|
pub struct Validator(crate::validator::Validator);
|
||||||
|
impl Validator{
|
||||||
|
pub const fn new(inner:crate::validator::Validator)->Self{
|
||||||
|
Self(inner)
|
||||||
|
}
|
||||||
|
pub async fn validate(&self,validate_info:ValidateSubmissionRequest)->Result<(),ValidateSubmissionError>{
|
||||||
|
let Self(validator)=self;
|
||||||
|
|
||||||
|
let submission_id=validate_info.SubmissionID;
|
||||||
|
let validate_result=validator.validate(validate_info.into()).await;
|
||||||
|
|
||||||
|
// update the submission depending on the result
|
||||||
|
match &validate_result{
|
||||||
|
Ok(())=>{
|
||||||
|
// update the submission model status to validated
|
||||||
|
validator.api.action_submission_validated(
|
||||||
|
submissions_api::types::SubmissionID(submission_id)
|
||||||
|
).await.map_err(ValidateSubmissionError::ApiActionSubmissionValidate)?;
|
||||||
|
},
|
||||||
|
Err(e)=>{
|
||||||
|
// update the submission model status to accepted
|
||||||
|
validator.api.action_submission_accepted(submissions_api::types::ActionSubmissionAcceptedRequest{
|
||||||
|
SubmissionID:submission_id,
|
||||||
|
StatusMessage:format!("{e}"),
|
||||||
|
}).await.map_err(ValidateSubmissionError::ApiActionSubmissionValidate)?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
|
use submissions_api::types::ResourceType;
|
||||||
|
|
||||||
use crate::nats_types::ValidateRequest;
|
use crate::types::ResourceID;
|
||||||
|
|
||||||
const SCRIPT_CONCURRENCY:usize=16;
|
const SCRIPT_CONCURRENCY:usize=16;
|
||||||
|
|
||||||
@@ -21,23 +22,33 @@ fn source_has_illegal_keywords(source:&str)->bool{
|
|||||||
source.find("getfenv").is_some()||source.find("require").is_some()
|
source.find("getfenv").is_some()||source.find("require").is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
fn hash_source(source:&str)->String{
|
||||||
|
let mut hasher=siphasher::sip::SipHasher::new();
|
||||||
|
std::hash::Hasher::write(&mut hasher,source.as_bytes());
|
||||||
|
let hash=std::hash::Hasher::finish(&hasher);
|
||||||
|
format!("{:016x}",hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ValidateError{
|
pub enum ValidateError{
|
||||||
Flagged,
|
ScriptFlaggedIllegalKeyword(String),
|
||||||
Blocked,
|
ScriptBlocked(Option<submissions_api::types::ScriptID>),
|
||||||
NotAllowed,
|
ScriptNotYetReviewed(Option<submissions_api::types::ScriptID>),
|
||||||
Get(rbx_asset::cookie::GetError),
|
ModelFileDownload(rbx_asset::cookie::GetError),
|
||||||
ReadDom(ReadDomError),
|
ModelFileDecode(ReadDomError),
|
||||||
ApiGetScriptPolicy(submissions_api::types::SingleItemError),
|
ApiGetScriptPolicyFromHash(submissions_api::types::SingleItemError),
|
||||||
ApiGetScript(submissions_api::Error),
|
ApiGetScript(submissions_api::Error),
|
||||||
ApiCreateScript(submissions_api::Error),
|
ApiCreateScript(submissions_api::Error),
|
||||||
ApiCreateScriptPolicy(submissions_api::Error),
|
ApiCreateScriptPolicy(submissions_api::Error),
|
||||||
|
ApiGetScriptFromHash(submissions_api::types::SingleItemError),
|
||||||
|
ApiUpdateMapfixModel(submissions_api::Error),
|
||||||
ApiUpdateSubmissionModel(submissions_api::Error),
|
ApiUpdateSubmissionModel(submissions_api::Error),
|
||||||
ApiActionSubmissionValidate(submissions_api::Error),
|
ModelFileRootMustHaveOneChild,
|
||||||
WriteDom(rbx_binary::EncodeError),
|
ModelFileChildRefIsNil,
|
||||||
Upload(rbx_asset::cookie::UploadError),
|
ModelFileEncode(rbx_binary::EncodeError),
|
||||||
Create(rbx_asset::cookie::CreateError),
|
AssetUpload(rbx_asset::cookie::UploadError),
|
||||||
|
AssetCreate(rbx_asset::cookie::CreateError),
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for ValidateError{
|
impl std::fmt::Display for ValidateError{
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
@@ -46,9 +57,38 @@ impl std::fmt::Display for ValidateError{
|
|||||||
}
|
}
|
||||||
impl std::error::Error for ValidateError{}
|
impl std::error::Error for ValidateError{}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
pub struct ValidateRequest{
|
||||||
|
pub ModelID:u64,
|
||||||
|
pub ModelVersion:u64,
|
||||||
|
pub ValidatedModelID:Option<u64>,
|
||||||
|
pub ResourceID:ResourceID,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<crate::nats_types::ValidateMapfixRequest> for ValidateRequest{
|
||||||
|
fn from(value:crate::nats_types::ValidateMapfixRequest)->Self{
|
||||||
|
Self{
|
||||||
|
ModelID:value.ModelID,
|
||||||
|
ModelVersion:value.ModelVersion,
|
||||||
|
ValidatedModelID:value.ValidatedModelID,
|
||||||
|
ResourceID:ResourceID::Mapfix(value.MapfixID),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<crate::nats_types::ValidateSubmissionRequest> for ValidateRequest{
|
||||||
|
fn from(value:crate::nats_types::ValidateSubmissionRequest)->Self{
|
||||||
|
Self{
|
||||||
|
ModelID:value.ModelID,
|
||||||
|
ModelVersion:value.ModelVersion,
|
||||||
|
ValidatedModelID:value.ValidatedModelID,
|
||||||
|
ResourceID:ResourceID::Submission(value.SubmissionID),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Validator{
|
pub struct Validator{
|
||||||
roblox_cookie:rbx_asset::cookie::CookieContext,
|
pub(crate) roblox_cookie:rbx_asset::cookie::CookieContext,
|
||||||
api:submissions_api::internal::Context,
|
pub(crate) api:submissions_api::internal::Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Validator{
|
impl Validator{
|
||||||
@@ -62,36 +102,14 @@ impl Validator{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub async fn validate(&self,validate_info:ValidateRequest)->Result<(),ValidateError>{
|
pub async fn validate(&self,validate_info:ValidateRequest)->Result<(),ValidateError>{
|
||||||
let submission_id=validate_info.SubmissionID;
|
|
||||||
let validate_result=self.validate_inner(validate_info).await;
|
|
||||||
|
|
||||||
// update the submission depending on the result
|
|
||||||
match &validate_result{
|
|
||||||
Ok(())=>{
|
|
||||||
// update the submission model status to validated
|
|
||||||
self.api.action_submission_validated(
|
|
||||||
submissions_api::types::SubmissionID(submission_id)
|
|
||||||
).await.map_err(ValidateError::ApiActionSubmissionValidate)?;
|
|
||||||
},
|
|
||||||
Err(_)=>{
|
|
||||||
// update the submission model status to accepted
|
|
||||||
self.api.action_submission_accepted(
|
|
||||||
submissions_api::types::SubmissionID(submission_id)
|
|
||||||
).await.map_err(ValidateError::ApiActionSubmissionValidate)?;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
validate_result
|
|
||||||
}
|
|
||||||
pub async fn validate_inner(&self,validate_info:ValidateRequest)->Result<(),ValidateError>{
|
|
||||||
// download map
|
// download map
|
||||||
let data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
|
let data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
|
||||||
asset_id:validate_info.ModelID,
|
asset_id:validate_info.ModelID,
|
||||||
version:Some(validate_info.ModelVersion),
|
version:Some(validate_info.ModelVersion),
|
||||||
}).await.map_err(ValidateError::Get)?;
|
}).await.map_err(ValidateError::ModelFileDownload)?;
|
||||||
|
|
||||||
// decode dom (slow!)
|
// decode dom (slow!)
|
||||||
let mut dom=read_dom(&mut std::io::Cursor::new(data)).map_err(ValidateError::ReadDom)?;
|
let mut dom=read_dom(&mut std::io::Cursor::new(data)).map_err(ValidateError::ModelFileDecode)?;
|
||||||
|
|
||||||
/* VALIDATE MAP */
|
/* VALIDATE MAP */
|
||||||
|
|
||||||
@@ -104,12 +122,14 @@ impl Validator{
|
|||||||
// check the source for illegal keywords
|
// check the source for illegal keywords
|
||||||
if source_has_illegal_keywords(source){
|
if source_has_illegal_keywords(source){
|
||||||
// immediately abort
|
// immediately abort
|
||||||
return Err(ValidateError::Flagged);
|
// grab path to offending script
|
||||||
|
let path=get_partial_path(&dom,script);
|
||||||
|
return Err(ValidateError::ScriptFlaggedIllegalKeyword(path));
|
||||||
}
|
}
|
||||||
// associate a name and policy with the source code
|
// associate a name and policy with the source code
|
||||||
// policy will be fetched from the database to replace the default policy
|
// policy will be fetched from the database to replace the default policy
|
||||||
script_map.insert(source.clone(),NamePolicy{
|
script_map.insert(source.clone(),NamePolicy{
|
||||||
name:script.name.clone(),
|
name:get_partial_path(&dom,script),
|
||||||
policy:Policy::None,
|
policy:Policy::None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -120,14 +140,12 @@ impl Validator{
|
|||||||
futures::stream::iter(script_map.iter_mut().map(Ok))
|
futures::stream::iter(script_map.iter_mut().map(Ok))
|
||||||
.try_for_each_concurrent(Some(SCRIPT_CONCURRENCY),|(source,NamePolicy{policy,name})|async{
|
.try_for_each_concurrent(Some(SCRIPT_CONCURRENCY),|(source,NamePolicy{policy,name})|async{
|
||||||
// get the hash
|
// get the hash
|
||||||
let mut hasher=siphasher::sip::SipHasher::new();
|
let hash=hash_source(source.as_str());
|
||||||
std::hash::Hasher::write(&mut hasher,source.as_bytes());
|
|
||||||
let hash=std::hash::Hasher::finish(&hasher);
|
|
||||||
|
|
||||||
// fetch the script policy
|
// fetch the script policy
|
||||||
let script_policy=self.api.get_script_policy_from_hash(submissions_api::types::HashRequest{
|
let script_policy=self.api.get_script_policy_from_hash(submissions_api::types::HashRequest{
|
||||||
hash:format!("{:016x}",hash).as_str(),
|
hash:hash.as_str(),
|
||||||
}).await.map_err(ValidateError::ApiGetScriptPolicy)?;
|
}).await.map_err(ValidateError::ApiGetScriptPolicyFromHash)?;
|
||||||
|
|
||||||
// write the policy to the script_map, fetching the replacement code if necessary
|
// write the policy to the script_map, fetching the replacement code if necessary
|
||||||
if let Some(script_policy)=script_policy{
|
if let Some(script_policy)=script_policy{
|
||||||
@@ -144,11 +162,17 @@ impl Validator{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}else{
|
}else{
|
||||||
|
let (resource_type,resource_id)=match validate_info.ResourceID{
|
||||||
|
ResourceID::Mapfix(mapfix_id)=>(ResourceType::Mapfix,mapfix_id),
|
||||||
|
ResourceID::Submission(submission_id)=>(ResourceType::Submission,submission_id),
|
||||||
|
};
|
||||||
|
|
||||||
// upload the script
|
// upload the script
|
||||||
let script=self.api.create_script(submissions_api::types::CreateScriptRequest{
|
let script=self.api.create_script(submissions_api::types::CreateScriptRequest{
|
||||||
Name:name.as_str(),
|
Name:name.as_str(),
|
||||||
Source:source.as_str(),
|
Source:source.as_str(),
|
||||||
SubmissionID:Some(validate_info.SubmissionID),
|
ResourceType:resource_type,
|
||||||
|
ResourceID:Some(resource_id),
|
||||||
}).await.map_err(ValidateError::ApiCreateScript)?;
|
}).await.map_err(ValidateError::ApiCreateScript)?;
|
||||||
|
|
||||||
// create a None policy (pending review by yours truly)
|
// create a None policy (pending review by yours truly)
|
||||||
@@ -169,10 +193,22 @@ impl Validator{
|
|||||||
if let Some(script)=dom.get_by_ref_mut(script_ref){
|
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"){
|
if let Some(rbx_dom_weak::types::Variant::String(source))=script.properties.get_mut("Source"){
|
||||||
match script_map.get(source.as_str()).map(|p|&p.policy){
|
match script_map.get(source.as_str()).map(|p|&p.policy){
|
||||||
Some(Policy::Blocked)=>return Err(ValidateError::Blocked),
|
Some(Policy::Blocked)=>{
|
||||||
|
let hash=hash_source(source.as_str());
|
||||||
|
let script=self.api.get_script_from_hash(submissions_api::types::HashRequest{
|
||||||
|
hash:hash.as_str(),
|
||||||
|
}).await.map_err(ValidateError::ApiGetScriptFromHash)?;
|
||||||
|
return Err(ValidateError::ScriptBlocked(script.map(|s|s.ID)));
|
||||||
|
},
|
||||||
None
|
None
|
||||||
|Some(Policy::None)
|
|Some(Policy::None)
|
||||||
=>return Err(ValidateError::NotAllowed),
|
=>{
|
||||||
|
let hash=hash_source(source.as_str());
|
||||||
|
let script=self.api.get_script_from_hash(submissions_api::types::HashRequest{
|
||||||
|
hash:hash.as_str(),
|
||||||
|
}).await.map_err(ValidateError::ApiGetScriptFromHash)?;
|
||||||
|
return Err(ValidateError::ScriptNotYetReviewed(script.map(|s|s.ID)));
|
||||||
|
},
|
||||||
Some(Policy::Allowed)=>(),
|
Some(Policy::Allowed)=>(),
|
||||||
Some(Policy::Delete)=>{
|
Some(Policy::Delete)=>{
|
||||||
modified=true;
|
modified=true;
|
||||||
@@ -194,7 +230,10 @@ impl Validator{
|
|||||||
if modified{
|
if modified{
|
||||||
// serialize model (slow!)
|
// serialize model (slow!)
|
||||||
let mut data=Vec::new();
|
let mut data=Vec::new();
|
||||||
rbx_binary::to_writer(&mut data,&dom,dom.root().children()).map_err(ValidateError::WriteDom)?;
|
let &[map_ref]=dom.root().children()else{
|
||||||
|
return Err(ValidateError::ModelFileRootMustHaveOneChild);
|
||||||
|
};
|
||||||
|
rbx_binary::to_writer(&mut data,&dom,&[map_ref]).map_err(ValidateError::ModelFileEncode)?;
|
||||||
|
|
||||||
// upload a model lol
|
// upload a model lol
|
||||||
let model_id=if let Some(model_id)=validate_info.ValidatedModelID{
|
let model_id=if let Some(model_id)=validate_info.ValidatedModelID{
|
||||||
@@ -206,29 +245,45 @@ impl Validator{
|
|||||||
ispublic:None,
|
ispublic:None,
|
||||||
allowComments:None,
|
allowComments:None,
|
||||||
groupId:None,
|
groupId:None,
|
||||||
},data).await.map_err(ValidateError::Upload)?;
|
},data).await.map_err(ValidateError::AssetUpload)?;
|
||||||
|
|
||||||
response.AssetId
|
response.AssetId
|
||||||
}else{
|
}else{
|
||||||
|
// grab the map instance from the map re
|
||||||
|
let Some(map_instance)=dom.get_by_ref(map_ref)else{
|
||||||
|
return Err(ValidateError::ModelFileChildRefIsNil);
|
||||||
|
};
|
||||||
// create new model
|
// create new model
|
||||||
let response=self.roblox_cookie.create(rbx_asset::cookie::CreateRequest{
|
let response=self.roblox_cookie.create(rbx_asset::cookie::CreateRequest{
|
||||||
name:dom.root().name.clone(),
|
name:map_instance.name.clone(),
|
||||||
description:"".to_owned(),
|
description:"".to_owned(),
|
||||||
ispublic:true,
|
ispublic:true,
|
||||||
allowComments:true,
|
allowComments:true,
|
||||||
groupId:None,
|
groupId:None,
|
||||||
},data).await.map_err(ValidateError::Create)?;
|
},data).await.map_err(ValidateError::AssetCreate)?;
|
||||||
|
|
||||||
response.AssetId
|
response.AssetId
|
||||||
};
|
};
|
||||||
|
|
||||||
// update the submission to use the validated model
|
match validate_info.ResourceID{
|
||||||
self.api.update_submission_model(submissions_api::types::UpdateSubmissionModelRequest{
|
ResourceID::Mapfix(mapfix_id)=>{
|
||||||
SubmissionID:validate_info.SubmissionID,
|
// update the mapfix to use the validated model
|
||||||
ModelID:model_id,
|
self.api.update_mapfix_validated_model(submissions_api::types::UpdateMapfixModelRequest{
|
||||||
ModelVersion:1, //TODO
|
MapfixID:mapfix_id,
|
||||||
}).await.map_err(ValidateError::ApiUpdateSubmissionModel)?;
|
ModelID:model_id,
|
||||||
};
|
ModelVersion:1, //TODO
|
||||||
|
}).await.map_err(ValidateError::ApiUpdateMapfixModel)?;
|
||||||
|
},
|
||||||
|
ResourceID::Submission(submission_id)=>{
|
||||||
|
// update the submission to use the validated model
|
||||||
|
self.api.update_submission_validated_model(submissions_api::types::UpdateSubmissionModelRequest{
|
||||||
|
SubmissionID:submission_id,
|
||||||
|
ModelID:model_id,
|
||||||
|
ModelVersion:1, //TODO
|
||||||
|
}).await.map_err(ValidateError::ApiUpdateSubmissionModel)?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -290,6 +345,19 @@ fn recursive_collect_superclass(objects:&mut std::vec::Vec<rbx_dom_weak::types::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_partial_path(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance)->String{
|
||||||
|
let mut names:Vec<_>=core::iter::successors(
|
||||||
|
Some(instance),
|
||||||
|
|i|dom.get_by_ref(i.parent())
|
||||||
|
).map(
|
||||||
|
|i|i.name.as_str()
|
||||||
|
).collect();
|
||||||
|
// discard the name of the root object
|
||||||
|
names.pop();
|
||||||
|
names.reverse();
|
||||||
|
names.join(".")
|
||||||
|
}
|
||||||
|
|
||||||
fn get_script_refs(dom:&rbx_dom_weak::WeakDom)->Vec<rbx_dom_weak::types::Ref>{
|
fn get_script_refs(dom:&rbx_dom_weak::WeakDom)->Vec<rbx_dom_weak::types::Ref>{
|
||||||
let mut scripts=std::vec::Vec::new();
|
let mut scripts=std::vec::Vec::new();
|
||||||
recursive_collect_superclass(&mut scripts,dom,dom.root(),"LuaSourceContainer");
|
recursive_collect_superclass(&mut scripts,dom,dom.root(),"LuaSourceContainer");
|
||||||
|
|||||||
@@ -3,15 +3,7 @@ import type { NextConfig } from "next";
|
|||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
distDir: "build",
|
distDir: "build",
|
||||||
output: "standalone",
|
output: "standalone",
|
||||||
rewrites: async () => {
|
images: {
|
||||||
return [
|
|
||||||
{
|
|
||||||
source: "/api/:path*",
|
|
||||||
destination: "http://localhost:8082/v1/:path*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
images: {
|
|
||||||
remotePatterns: [
|
remotePatterns: [
|
||||||
{
|
{
|
||||||
protocol: 'https',
|
protocol: 'https',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev -p 3000",
|
"dev": "next dev -p 3000 --turbopack",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start -p 3000",
|
"start": "next start -p 3000",
|
||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
|
|||||||
@@ -1,8 +1,27 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
import Header from "./header";
|
import Header from "./header";
|
||||||
|
|
||||||
|
async function login_check() {
|
||||||
|
const response = await fetch("/api/session/validate")
|
||||||
|
if (response.ok) {
|
||||||
|
const logged_in = await response.json()
|
||||||
|
if (!logged_in) {
|
||||||
|
redirect("https://auth.staging.strafes.net/oauth2/login?redirect=" + window.location.href)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("No response from /api/session/validate")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function Webpage({children}: Readonly<{children?: React.ReactNode}>) {
|
export default function Webpage({children}: Readonly<{children?: React.ReactNode}>) {
|
||||||
return (<>
|
useEffect(() => { login_check() }, [])
|
||||||
<Header/>
|
|
||||||
{children}
|
return <>
|
||||||
</>)
|
<Header/>
|
||||||
}
|
{children}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $form-label-fontsize: 1.3rem;
|
|||||||
:root {
|
:root {
|
||||||
color-scheme: light dark;
|
color-scheme: light dark;
|
||||||
|
|
||||||
--header-height: 60px;
|
--header-height: 45px;
|
||||||
|
|
||||||
--page: white;
|
--page: white;
|
||||||
--header-grad-left: #363b40;
|
--header-grad-left: #363b40;
|
||||||
|
|||||||
@@ -2,15 +2,6 @@
|
|||||||
|
|
||||||
@use "../../globals.scss";
|
@use "../../globals.scss";
|
||||||
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: calc(100vh - var(--header-height));
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color:rgb(255, 255, 255);
|
color:rgb(255, 255, 255);
|
||||||
|
|
||||||
@@ -21,4 +12,64 @@ a {
|
|||||||
&:active {
|
&:active {
|
||||||
color: rgb(192, 192, 192)
|
color: rgb(192, 192, 192)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||||
|
grid-template-rows: repeat(3, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination button {
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
font-size: 1.15rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.35rem;
|
||||||
|
background-color: #33333350;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination button:disabled {
|
||||||
|
background-color: #5555559a;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-dots {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.35rem;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #bbb;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot.active {
|
||||||
|
background-color: #333;
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,87 @@
|
|||||||
@use "../../../globals.scss";
|
@use "../../../globals.scss";
|
||||||
|
|
||||||
.submissionCard {
|
.submissionCard {
|
||||||
@include globals.border-with-radius;
|
display: flex;
|
||||||
|
|
||||||
background-color: #2020207c;
|
background-color: #2020207c;
|
||||||
border: 1px solid #501717;
|
border: 1px solid #97979783;
|
||||||
border-radius: 6px;
|
border-radius: 10px;
|
||||||
padding: 6px;
|
box-sizing: border-box;
|
||||||
text-align: center;
|
flex-direction: column;
|
||||||
font-size: 14px;
|
justify-content: space-between;
|
||||||
|
height: 100%;
|
||||||
|
min-width: 180px;
|
||||||
|
max-width: 340px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details {
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 3px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 3px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-image {
|
||||||
|
border-radius: 10px 10px 0 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
> img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.displayName {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 70%;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-grow: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author span {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating {
|
||||||
|
margin-left: auto;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
@@ -9,9 +9,10 @@ interface CommentersProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface CreatorAndReviewStatus {
|
interface CreatorAndReviewStatus {
|
||||||
asset_id: SubmissionInfo["AssetID"],
|
asset_id: SubmissionInfo["AssetID"],
|
||||||
creator: SubmissionInfo["DisplayName"],
|
creator: SubmissionInfo["DisplayName"],
|
||||||
review: SubmissionInfo["StatusID"],
|
review: SubmissionInfo["StatusID"],
|
||||||
|
status_message: SubmissionInfo["StatusMessage"],
|
||||||
comments: Comment[],
|
comments: Comment[],
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,40 @@
|
|||||||
import { Button, ButtonOwnProps } from "@mui/material";
|
import { Button, ButtonOwnProps } from "@mui/material";
|
||||||
import { SubmissionInfo } from "@/app/ts/Submission";
|
|
||||||
|
|
||||||
type Actions = "Completed" | "Submit" | "Reject" | "Revoke"
|
type Actions = "Completed" | "Submit" | "Reject" | "Revoke"
|
||||||
type Review = Actions | "Accept" | "Validate" | "Upload"
|
type ApiActions = Lowercase<Actions> | "trigger-validate" | "retry-validate" | "trigger-upload" | "reset-uploading" | "reset-validating"
|
||||||
type Action = Lowercase<Actions> | "trigger-validate" | "trigger-upload"
|
type Review = Actions | "Accept" | "Validate" | "Upload" | "Reset Uploading (fix softlocked status)" | "Reset Validating (fix softlocked status)" | "Request Changes"
|
||||||
|
|
||||||
interface ReviewButton {
|
interface ReviewButton {
|
||||||
name: Review,
|
name: Review,
|
||||||
action: Action,
|
action: ApiActions,
|
||||||
submissionId: string,
|
submissionId: string,
|
||||||
color: ButtonOwnProps["color"]
|
color: ButtonOwnProps["color"]
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReviewButtonClicked(action: Action, submissionId: string) {
|
interface ReviewId {
|
||||||
fetch(`/api/submissions/${submissionId}/status/${action}`, {
|
submissionId: string
|
||||||
method: "POST",
|
}
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json",
|
async function ReviewButtonClicked(action: ApiActions, submissionId: string) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/submissions/${submissionId}/status/${action}`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Check if the HTTP request was successful
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorDetails = await response.text();
|
||||||
|
|
||||||
|
// Throw an error with detailed information
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}, details: ${errorDetails}`);
|
||||||
}
|
}
|
||||||
}).then(() => { window.location.reload(); })
|
|
||||||
|
window.location.reload();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating submission status:", error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReviewButton(props: ReviewButton) {
|
function ReviewButton(props: ReviewButton) {
|
||||||
@@ -28,8 +44,8 @@ function ReviewButton(props: ReviewButton) {
|
|||||||
onClick={() => { ReviewButtonClicked(props.action, props.submissionId) }}>{props.name}</Button>
|
onClick={() => { ReviewButtonClicked(props.action, props.submissionId) }}>{props.name}</Button>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ReviewButtons(props: SubmissionInfo) {
|
export default function ReviewButtons(props: ReviewId) {
|
||||||
const submissionId = props.ID.toString()
|
const submissionId = props.submissionId
|
||||||
// When is each button visible?
|
// When is each button visible?
|
||||||
// Multiple buttons can be visible at once.
|
// Multiple buttons can be visible at once.
|
||||||
// Action | Role | When Current Status is One of:
|
// Action | Role | When Current Status is One of:
|
||||||
@@ -38,17 +54,21 @@ export default function ReviewButtons(props: SubmissionInfo) {
|
|||||||
// Revoke | Submitter | Submitted, ChangesRequested
|
// Revoke | Submitter | Submitted, ChangesRequested
|
||||||
// Accept | Reviewer | Submitted
|
// Accept | Reviewer | Submitted
|
||||||
// Validate | Reviewer | Accepted
|
// Validate | Reviewer | Accepted
|
||||||
|
// ResetValidating| Reviewer | Validating
|
||||||
// Reject | Reviewer | Submitted
|
// Reject | Reviewer | Submitted
|
||||||
// RequestChanges | Reviewer | Validated, Accepted, Submitted
|
// RequestChanges | Reviewer | Validated, Accepted, Submitted
|
||||||
// Upload | MapAdmin | Validated
|
// Upload | MapAdmin | Validated
|
||||||
|
// ResetUploading | MapAdmin | Uploading
|
||||||
return (
|
return (
|
||||||
<section className="review-set">
|
<section className="review-set">
|
||||||
<ReviewButton color="info" name="Submit" action="submit" submissionId={submissionId}/>
|
<ReviewButton color="info" name="Submit" action="submit" submissionId={submissionId}/>
|
||||||
<ReviewButton color="info" name="Revoke" action="revoke" submissionId={submissionId}/>
|
<ReviewButton color="info" name="Revoke" action="revoke" submissionId={submissionId}/>
|
||||||
<ReviewButton color="info" name="Accept" action="trigger-validate" submissionId={submissionId}/>
|
<ReviewButton color="info" name="Accept" action="trigger-validate" submissionId={submissionId}/>
|
||||||
<ReviewButton color="info" name="Validate" action="trigger-validate" submissionId={submissionId}/>
|
<ReviewButton color="info" name="Validate" action="retry-validate" submissionId={submissionId}/>
|
||||||
<ReviewButton color="error" name="Reject" action="reject" submissionId={submissionId}/>
|
<ReviewButton color="error" name="Reject" action="reject" submissionId={submissionId}/>
|
||||||
<ReviewButton color="info" name="Upload" action="trigger-upload" submissionId={submissionId}/>
|
<ReviewButton color="info" name="Upload" action="trigger-upload" submissionId={submissionId}/>
|
||||||
|
<ReviewButton color="error" name="Reset Uploading (fix softlocked status)" action="reset-uploading" submissionId={submissionId}/>
|
||||||
|
<ReviewButton color="error" name="Reset Validating (fix softlocked status)" action="reset-validating" submissionId={submissionId}/>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ import { useState, useEffect } from "react";
|
|||||||
|
|
||||||
import "./(styles)/page.scss";
|
import "./(styles)/page.scss";
|
||||||
|
|
||||||
|
interface ReviewId {
|
||||||
|
submissionId: string
|
||||||
|
}
|
||||||
|
|
||||||
function Ratings() {
|
function Ratings() {
|
||||||
return (
|
return (
|
||||||
<Window className="rating-window" title="Rating">
|
<Window className="rating-window" title="Rating">
|
||||||
@@ -35,15 +39,14 @@ function Ratings() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function RatingArea(submission: SubmissionInfo) {
|
function RatingArea(submission: ReviewId) {
|
||||||
return (
|
return (
|
||||||
<aside className="review-area">
|
<aside className="review-area">
|
||||||
<section className="map-image-area">
|
<section className="map-image-area">
|
||||||
<MapImage/>
|
<MapImage/>
|
||||||
</section>
|
</section>
|
||||||
<Ratings/>
|
<Ratings/>
|
||||||
{/* TODO: NOT DO!!! */} {ReviewButtons(submission)}
|
<ReviewButtons submissionId={submission.submissionId}/>
|
||||||
{/* <ReviewButtons submissionId={submission.ID}/> */}
|
|
||||||
</aside>
|
</aside>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -51,6 +54,7 @@ function RatingArea(submission: SubmissionInfo) {
|
|||||||
function TitleAndComments(stats: CreatorAndReviewStatus) {
|
function TitleAndComments(stats: CreatorAndReviewStatus) {
|
||||||
const Review = SubmissionStatusToString(stats.review)
|
const Review = SubmissionStatusToString(stats.review)
|
||||||
|
|
||||||
|
// TODO: hide status message when status is not "Accepted"
|
||||||
return (
|
return (
|
||||||
<main className="review-info">
|
<main className="review-info">
|
||||||
<div>
|
<div>
|
||||||
@@ -61,6 +65,7 @@ function TitleAndComments(stats: CreatorAndReviewStatus) {
|
|||||||
</div>
|
</div>
|
||||||
<p className="by-creator">by <Link href="" target="_blank">{stats.creator}</Link></p>
|
<p className="by-creator">by <Link href="" target="_blank">{stats.creator}</Link></p>
|
||||||
<p className="asset-id">Model Asset ID {stats.asset_id}</p>
|
<p className="asset-id">Model Asset ID {stats.asset_id}</p>
|
||||||
|
<p className="status-message">Validation Error: {stats.status_message}</p>
|
||||||
<span className="spacer"></span>
|
<span className="spacer"></span>
|
||||||
<Comments comments_data={stats}/>
|
<Comments comments_data={stats}/>
|
||||||
</main>
|
</main>
|
||||||
@@ -91,8 +96,8 @@ export default function SubmissionInfoPage() {
|
|||||||
<Webpage>
|
<Webpage>
|
||||||
<main className="map-page-main">
|
<main className="map-page-main">
|
||||||
<section className="review-section">
|
<section className="review-section">
|
||||||
{RatingArea(submission)}
|
<RatingArea submissionId={dynamicId.submissionId}/>
|
||||||
<TitleAndComments name={submission.DisplayName} creator={submission.Creator} review={submission.StatusID} asset_id={submission.AssetID} comments={[]}/>
|
<TitleAndComments name={submission.DisplayName} creator={submission.Creator} review={submission.StatusID} status_message={submission.StatusMessage} asset_id={submission.AssetID} comments={[]}/>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</Webpage>
|
</Webpage>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { Rating } from "@mui/material";
|
||||||
|
|
||||||
interface SubmissionCardProps {
|
interface SubmissionCardProps {
|
||||||
displayName: string;
|
displayName: string;
|
||||||
@@ -14,11 +15,26 @@ export default function SubmissionCard(props: SubmissionCardProps) {
|
|||||||
return (
|
return (
|
||||||
<Link href={`/submissions/${props.id}`}>
|
<Link href={`/submissions/${props.id}`}>
|
||||||
<div className="submissionCard">
|
<div className="submissionCard">
|
||||||
{/* TODO: Grab image of model */}
|
<div className="content">
|
||||||
<Image height={200} width={200} priority={true} src="https://api.ic3.space/strafe/map-images/11222350808" style={{ width: `100%` }} alt={props.displayName} />
|
<div className="map-image">
|
||||||
<h3>{props.displayName}</h3>
|
{/* TODO: Grab image of model */}
|
||||||
<p>By {props.author}</p>
|
<Image height={200} width={200} priority={true} src="https://api.ic3.space/strafe/map-images/11222350808" style={{ width: `100%` }} alt={props.displayName} />
|
||||||
<p>⭐ {props.rating}</p> {/* TODO: paste the star element from submission/1 page */}
|
</div>
|
||||||
|
<div className="details">
|
||||||
|
<div className="header">
|
||||||
|
<span className="displayName">{props.displayName}</span>
|
||||||
|
<div className="rating">
|
||||||
|
<Rating value={props.rating} readOnly size="small" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="footer">
|
||||||
|
<div className="author">
|
||||||
|
<Image className="avatar" width={28} height={28} priority={true} src="https://api.ic3.space/strafe/map-images/11222350808" alt={props.author}/>
|
||||||
|
<span>{props.author}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
//This can all be solved using 0 JavaScript,
|
|
||||||
//display: grid, ->1fr unit<-
|
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
|
||||||
import { Grid, Skeleton } from '@mui/material';
|
|
||||||
|
|
||||||
const elementWidth = 220;
|
|
||||||
|
|
||||||
function calculateSkeletonCount(setState: React.Dispatch<React.SetStateAction<number>>) {
|
|
||||||
const viewportWidth = window.innerWidth - 100 * 2;
|
|
||||||
setState(Math.floor(viewportWidth / elementWidth) * 2);
|
|
||||||
};
|
|
||||||
|
|
||||||
function SkeletonGrid() {
|
|
||||||
const [skeletonCount, setSkeletonCount] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
calculateSkeletonCount(setSkeletonCount);
|
|
||||||
window.addEventListener('resize', () => { calculateSkeletonCount(setSkeletonCount) });
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('resize', () => { calculateSkeletonCount(setSkeletonCount) });
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
spacing={2}
|
|
||||||
alignItems="center"
|
|
||||||
justifyContent="center"
|
|
||||||
style={{ maxWidth: 'calc(100vw - 100px)', margin: '0 auto' }}
|
|
||||||
>
|
|
||||||
{Array.from({ length: skeletonCount }).map((_, index) => (
|
|
||||||
<Grid item key={index}>
|
|
||||||
<Skeleton variant="rectangular" width={215} height={340} />
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SkeletonGrid;
|
|
||||||
@@ -1,33 +1,61 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from "react";
|
||||||
import { SubmissionInfo } from '../ts/Submission';
|
import { SubmissionInfo } from "../ts/Submission";
|
||||||
import { Grid2 as Grid } from '@mui/material';
|
|
||||||
import SubmissionCard from "./_card";
|
import SubmissionCard from "./_card";
|
||||||
import SkeletonGrid from './_loading';
|
|
||||||
import Webpage from "@/app/_components/webpage";
|
import Webpage from "@/app/_components/webpage";
|
||||||
|
|
||||||
import "./(styles)/page.scss";
|
import "./(styles)/page.scss";
|
||||||
|
|
||||||
export default function SubmissionInfoPage() {
|
export default function SubmissionInfoPage() {
|
||||||
const [submissions, setSubmissions] = useState<SubmissionInfo[]>([])
|
const [submissions, setSubmissions] = useState<SubmissionInfo[]>([])
|
||||||
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
|
const cardsPerPage = 24; // built to fit on a 1920x1080 monitor
|
||||||
|
|
||||||
useEffect(() => { // needs to be client sided since server doesn't have a session, nextjs got mad at me for exporting an async function: (https://nextjs.org/docs/messages/no-async-client-component)
|
const totalPages = Math.ceil(submissions.length / cardsPerPage);
|
||||||
|
|
||||||
|
const currentCards = submissions.slice(
|
||||||
|
currentPage * cardsPerPage,
|
||||||
|
(currentPage + 1) * cardsPerPage
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextPage = () => {
|
||||||
|
if (currentPage < totalPages - 1) {
|
||||||
|
setCurrentPage(currentPage + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const prevPage = () => {
|
||||||
|
if (currentPage > 0) {
|
||||||
|
setCurrentPage(currentPage - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
async function fetchSubmissions() {
|
async function fetchSubmissions() {
|
||||||
const res = await fetch('/api/submissions?Page=1&Limit=100')
|
const res = await fetch('/api/submissions?Page=1&Limit=100')
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
setSubmissions(await res.json())
|
setSubmissions(await res.json())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setTimeout(() => { // testing loading screen made by chatGerbertPT
|
|
||||||
|
setTimeout(() => {
|
||||||
fetchSubmissions()
|
fetchSubmissions()
|
||||||
}, 250);
|
}, 50);
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
if (!submissions) {
|
if (!submissions) {
|
||||||
return <Webpage>
|
return <Webpage>
|
||||||
<main style={{ display: 'flex', justifyContent: 'center', padding: '1rem' }}>
|
<main>
|
||||||
<SkeletonGrid />
|
Loading...
|
||||||
|
</main>
|
||||||
|
</Webpage>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submissions && submissions.length == 0) {
|
||||||
|
return <Webpage>
|
||||||
|
<main>
|
||||||
|
Submissions list is empty.
|
||||||
</main>
|
</main>
|
||||||
</Webpage>
|
</Webpage>
|
||||||
}
|
}
|
||||||
@@ -35,43 +63,48 @@ export default function SubmissionInfoPage() {
|
|||||||
return (
|
return (
|
||||||
// TODO: Add filter settings & searchbar & page selector
|
// TODO: Add filter settings & searchbar & page selector
|
||||||
<Webpage>
|
<Webpage>
|
||||||
<main style={{ display: 'flex', justifyContent: 'center', padding: '1rem' }}>
|
<main
|
||||||
<Grid
|
style={{
|
||||||
container
|
display: 'flex',
|
||||||
spacing={2}
|
flexDirection: 'column',
|
||||||
alignItems="center"
|
justifyContent: 'center',
|
||||||
justifyContent="center"
|
alignItems: 'center',
|
||||||
style={{ maxWidth: 'calc(100vw - 100px)', margin: '0 auto' }}
|
padding: '1rem',
|
||||||
>
|
width: '100%',
|
||||||
{submissions.map((submission) => (
|
maxWidth: '100vw',
|
||||||
<Grid key={submission.ID}>
|
boxSizing: 'border-box',
|
||||||
<SubmissionCard
|
overflowX: 'hidden'
|
||||||
id={submission.ID}
|
}}
|
||||||
assetId={submission.AssetID}
|
>
|
||||||
displayName={submission.DisplayName}
|
<div className="pagination-dots">
|
||||||
author={submission.Creator}
|
{Array.from({ length: totalPages }).map((_, index) => (
|
||||||
rating={submission.StatusID}
|
<span
|
||||||
/>
|
key={index}
|
||||||
</Grid>
|
className={`dot ${index === currentPage ? 'active' : ''}`}
|
||||||
|
onClick={() => setCurrentPage(index)}
|
||||||
|
></span>
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</div>
|
||||||
|
<div className="pagination">
|
||||||
|
<button onClick={prevPage} disabled={currentPage === 0}><</button>
|
||||||
|
<span>
|
||||||
|
Page {currentPage + 1} of {totalPages}
|
||||||
|
</span>
|
||||||
|
<button onClick={nextPage} disabled={currentPage === totalPages - 1}>></button>
|
||||||
|
</div>
|
||||||
|
<div className="grid">
|
||||||
|
{currentCards.map((submission) => (
|
||||||
|
<SubmissionCard
|
||||||
|
key={submission.ID}
|
||||||
|
id={submission.ID}
|
||||||
|
assetId={submission.AssetID}
|
||||||
|
displayName={submission.DisplayName}
|
||||||
|
author={submission.Creator}
|
||||||
|
rating={submission.StatusID}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</Webpage>
|
</Webpage>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
// {
|
|
||||||
// "ID": 1,
|
|
||||||
// "DisplayName": "81bfc7a",
|
|
||||||
// "Creator": "79fbe8d",
|
|
||||||
// "GameID": 1073741824,
|
|
||||||
// "CreatedAt": 1734490019,
|
|
||||||
// "UpdatedAt": 1734565641,
|
|
||||||
// "Submitter": 1,
|
|
||||||
// "AssetID": 6438937102481093,
|
|
||||||
// "AssetVersion": 1225679040570074,
|
|
||||||
// "Completed": false,
|
|
||||||
// "SubmissionType": 0,
|
|
||||||
// "TargetAssetID": 1057095197389979,
|
|
||||||
// "StatusID": 4
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ const BootstrapInput = styled(InputBase)(({ theme }) => ({
|
|||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
padding: '10px 26px 10px 12px',
|
padding: '10px 26px 10px 12px',
|
||||||
transition: theme.transitions.create(['border-color', 'box-shadow']),
|
transition: theme.transitions.create(['border-color', 'box-shadow']),
|
||||||
// Use the system font instead of the default Roboto font.
|
|
||||||
fontFamily: [
|
fontFamily: [
|
||||||
'-apple-system',
|
'-apple-system',
|
||||||
'BlinkMacSystemFont',
|
'BlinkMacSystemFont',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { FormControl, FormControlLabel, Button, TextField, Checkbox } from "@mui/material"
|
import { Button, TextField } from "@mui/material"
|
||||||
|
|
||||||
import GameSelection from "./_game";
|
import GameSelection from "./_game";
|
||||||
import SendIcon from '@mui/icons-material/Send';
|
import SendIcon from '@mui/icons-material/Send';
|
||||||
@@ -15,7 +15,6 @@ interface SubmissionPayload {
|
|||||||
GameID: number;
|
GameID: number;
|
||||||
AssetID: number;
|
AssetID: number;
|
||||||
AssetVersion: number;
|
AssetVersion: number;
|
||||||
TargetAssetID: number;
|
|
||||||
}
|
}
|
||||||
interface IdResponse {
|
interface IdResponse {
|
||||||
ID: number;
|
ID: number;
|
||||||
@@ -23,7 +22,6 @@ interface IdResponse {
|
|||||||
|
|
||||||
export default function SubmissionInfoPage() {
|
export default function SubmissionInfoPage() {
|
||||||
const [game, setGame] = useState(1);
|
const [game, setGame] = useState(1);
|
||||||
const [isFixingMap, setIsFixingMap] = useState(false);
|
|
||||||
|
|
||||||
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -37,7 +35,6 @@ export default function SubmissionInfoPage() {
|
|||||||
GameID: game,
|
GameID: game,
|
||||||
AssetID: Number((formData.get("asset-id") as string) ?? "0"),
|
AssetID: Number((formData.get("asset-id") as string) ?? "0"),
|
||||||
AssetVersion: 0,
|
AssetVersion: 0,
|
||||||
TargetAssetID: isFixingMap ? Number((formData.get("target-asset-id") as string) ?? "0") : 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(payload)
|
console.log(payload)
|
||||||
@@ -51,6 +48,14 @@ export default function SubmissionInfoPage() {
|
|||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check if the HTTP request was successful
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorDetails = await response.text();
|
||||||
|
|
||||||
|
// Throw an error with detailed information
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}, details: ${errorDetails}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Allow any HTTP status
|
// Allow any HTTP status
|
||||||
const id_response:IdResponse = await response.json();
|
const id_response:IdResponse = await response.json();
|
||||||
|
|
||||||
@@ -76,15 +81,6 @@ export default function SubmissionInfoPage() {
|
|||||||
<TextField className="form-field" id="asset-id" name="asset-id" label="Asset ID" variant="outlined"/>
|
<TextField className="form-field" id="asset-id" name="asset-id" label="Asset ID" variant="outlined"/>
|
||||||
{/* I think this is Quat's job to figure this one out (to be set when someone clicks review(?)) */} {/* <TextField className="form-field" id="asset-version" label="Asset Version" variant="outlined"/> */}
|
{/* I think this is Quat's job to figure this one out (to be set when someone clicks review(?)) */} {/* <TextField className="form-field" id="asset-version" label="Asset Version" variant="outlined"/> */}
|
||||||
<GameSelection game={game} setGame={setGame} />
|
<GameSelection game={game} setGame={setGame} />
|
||||||
<FormControl>
|
|
||||||
<FormControlLabel control={<Checkbox sx={{
|
|
||||||
color: "#646464",
|
|
||||||
'&.Mui-checked': {
|
|
||||||
color: "#66BB6A",
|
|
||||||
},
|
|
||||||
}} onChange={(e) => setIsFixingMap(e.target.checked)} />} label="Fixing an Existing Map?" />
|
|
||||||
</FormControl>
|
|
||||||
<TextField className="form-field" id="target-asset-id" name="target-asset-id" label="Target Asset ID (group model)" variant="outlined"/>
|
|
||||||
<span className="spacer form-spacer"></span>
|
<span className="spacer form-spacer"></span>
|
||||||
<Button type="submit" variant="contained" startIcon={<SendIcon/>} sx={{
|
<Button type="submit" variant="contained" startIcon={<SendIcon/>} sx={{
|
||||||
width: "400px",
|
width: "400px",
|
||||||
|
|||||||
@@ -20,9 +20,12 @@ interface SubmissionInfo {
|
|||||||
readonly Submitter: number,
|
readonly Submitter: number,
|
||||||
readonly AssetID: number,
|
readonly AssetID: number,
|
||||||
readonly AssetVersion: number,
|
readonly AssetVersion: number,
|
||||||
|
readonly ValidatedAssetID: number,
|
||||||
|
readonly ValidatedAssetVersion: number,
|
||||||
readonly Completed: boolean,
|
readonly Completed: boolean,
|
||||||
readonly TargetAssetID: number,
|
readonly TargetAssetID: number,
|
||||||
readonly StatusID: SubmissionStatus
|
readonly StatusID: SubmissionStatus
|
||||||
|
readonly StatusMessage: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
function SubmissionStatusToString(submission_status: SubmissionStatus): string {
|
function SubmissionStatusToString(submission_status: SubmissionStatus): string {
|
||||||
|
|||||||
13
web/src/middleware.ts
Normal file
13
web/src/middleware.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server"
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
matcher: ["/api/:path*"],
|
||||||
|
}
|
||||||
|
|
||||||
|
export function middleware(request: NextRequest) {
|
||||||
|
if (!process.env.API_HOST) {
|
||||||
|
throw new Error("env variable \"API_HOST\" is not set")
|
||||||
|
}
|
||||||
|
const url = new URL(process.env.API_HOST + request.nextUrl.pathname.replace(/^\/api/, '') + request.nextUrl.search)
|
||||||
|
return NextResponse.rewrite(url, { request })
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user